This project is read-only.

Getting occasional error System.Net.FtpClient.FtpCommandException: User Exit denies Userid 'myUserID' from using Command 'CWD'

Aug 23, 2013 at 3:44 PM
JP, I see that CWD is called in the OpenRead when m_threadSafeDataChannels is true.
Should I make m_threadSafeDataChannels false? What is the downside of doing that?

Aug 23, 2013 at 4:01 PM
You cannot execute commands on the control connection while a transfer is taking place, the FTP protocol is not designed to allow it. System.Net.FtpClient's solution to this limitation is to clone the control connection for a download or upload, which means establishing a brand new connection to the server used solely for the file transfer. This free's up the FtpClient object to do other things while a transfer is taking place. Setting EnableThreadSafeDataChannels = false stops FtpClient from cloning itself which means you cannot safely do anything with your FtpClient object while a transfer is in progress.

So, in short, you can set EnableThreadSafeDataChannels to false if you do not need concurrency or have your own approach to solving the problem.

This is safe:
client.EnableThreadSafeDataChannels = false;
using(stream = client.OpenRead()) {
   // do transfer
This is not safe:
client.EnableThreadSafeDataChannels = false;

stream1 = client.OpenRead();
stream2 = client.OpenRead(); // we have a transfer in progress, can't do this!

client.GetListing(); // can't do this or any other operation on the server either!
This however is safe:
client.EnableThreadSafeDataChannels = true;

stream1 = client.OpenRead();
stream2 = client.OpenRead(); // stream1 has its own internal FtpClient object so this is OK!
Aug 23, 2013 at 4:04 PM
BTW, it would be helpful to see a transaction log, I don't know what the error in the title means. It was something sent from the server, not generated internally. Seeing the transaction log could help figure out why the server might have sent it.
Aug 23, 2013 at 4:15 PM
OK, I will work on getting the transaction log operational. The software this code is going into is not multithreading anything so I should be able to set EnableThreadSafeDataChannels to false.