FTP error 500

years ago I made with Xojo a FTP client app, using two TCP sockets (ftpCommands and ftpData).
Yesterday I submitted a new version to MAS, and the reviewer send me a note saying that transfers aborted showing this server-message: “An error occurred: 500 'CWD ': command not understood.”
I made some search on the NET, and I saw a lot of results referring to SSL, Port 21 instead of Passive Transfer Mode, etc. etc. So many that I felt lost.

I wonder if anybody could shed some light on it.
Meantime, since --as I said-- SSL was referred to, I switched the two TPC sockets to SSLsocket (with no other modification), and testing myself the app it seems to work all right as it did before (connecting to the server, transferring files, creating directories, deleting items etc.); but before submitting a new binary, I’d like to know if there is anything else I should consider about it. I mean, is there anything particular I should know/do when dealing with SSLsocket in place of TCPsocket?

Or could the problem be related to the fact that, as shown in the log below, the reviewer tested the app using a local server instead of a remote one?
In such case, can anybody tell me how to set up server.local as the reviewer did, so that I may test the app myself?

Or I could answer the reviewer saying that my app is supposed to work with remote servers only. And in such case, I’d have only to specify it in the meta > Description.

As you see, I’m am in the fog…
Suggestions welcome. Thank you.

This is the log saved by the app. The “An error occurred: 500 'CWD ': command not understood.” line is the last one.

Connecting to server.local [...]
220 ..
.** FTP server (tnftpd 20100324+GSSAPI) ready.
USER ftptest
331 User ftptest accepted, provide password.
230 User ftptest logged in.
215 UNIX Type: L8 Version: tnftpd 20100324+GSSAPI
257 “/” is the current directory.
227 Entering Passive Mode (...,255,92)
150 Opening ASCII mode data connection for ‘/bin/ls’.
226 Transfer complete.
CWD /Animated GIF
250 CWD command successful.
257 “/Animated GIF” is the current directory.
PASV port 65372
227 Entering Passive Mode (
150 Opening ASCII mode data connection for ‘/bin/ls’.
200 Type set to I.
PASV port 65373
227 Entering Passive Mode (
RETR /Animated GIF/200px-Rotating_earth_(large).gif
150 Opening BINARY mode data connection for ‘/Animated GIF/200px-Rotating_earth_(large).gif’ (143360 bytes).
Downloading 200px-Rotating_earth_(large).gif
Transferred 0 bytes in 1 sec (40 KB/s) - Transfer succeded
200 Type set to I.
PASV port 65374
227 Entering Passive Mode (
RETR /Animated GIF/Animated-GIF-Banana.gif
150 Opening BINARY mode data connection for ‘/Animated GIF/Animated-GIF-Banana.gif’ (73623 bytes).
Downloading Animated-GIF-Banana.gif
Transferred 0 bytes in 1 sec (120 KB/s) - Transfer succeded
An error occurred: 500 'CWD ': command not understood.

Does your app actually issue a CWD command with no path argument, or is the argument being truncated somehow? Either way I suspect that a missing path argument is the problem.

@Andrew Lambert Thank you for answering.
What you say is one of the many cases I found googling for “error 500”.

The app builds the path argument for each CWD command, and it always contain at least a “/”.
What I thing is happening, is that since the app is sandboxed, the path may not be available since the user has not accessed that local path by an Open/Save Dialog; therefore since the app has no permission to access the path, the path argument for CWD changes to “”, and the error 500 is fired.

If this is a reasonable explanation, then one way to deal with this issue could be to show an Open Dialog, the user clicks OK/Open and hopefully the app could run without problems. But I don’t like it.

Another way is to tell the user that the chosen path cannot be accessed, and then close the connection. But why should the app connect to a (local) server when it knows that it won’t be able to deal succesfuly with it?

So, since the app is addressed to users using remote servers, at present I’d like to bar connection to local servers, but for this I should know how to detect if the url to be accessed refers to a local server.
The Apple reviewer entered “server.local”: for Macs, is this the only possible URL, or are there other URLs or other ways to catch a local server before connecting to it?

Suggestions will be appreciated.
Thank you.

I am making a few assumptions here as I don’t know how your FTP client works so this is a bit of a fish:

“server.local” will just resolve to the IP of the machine named server on their “.local” domain, server just happened to be its assigned name in this example and could literally be anything if they changed it.

In this instance, server.local is probably a macos server that the reviewer is using to test ftp clients, it probably isn’t running on the “local machine” (but it might even be in a vm). The tell being “tnftpd 20100324+GSSAPI” which I believe was used in OS X 10.8 Mountain Lion Server.

As it is running here, it would be equivalent to a remote FTP server (even if it were running on the local machine) so I’m not sure why you’re referencing Open Dialog’s being an issue which will relate to the client end unless your FTP client sync’s/tracks the folder changes between the client<>server and a failure of the client to move to “/” ends up with a failure to send the correct “CWD /” to the server.

Removing access to “local” FTP servers is not the solution, if the FTP server has access to its “/” folder, your client should be able to work correctly with that. As Andrew mentions, it would seem that you’ve sent an empty CWD without the / which would cause the error returned to the reviewer. You’ll need to get to the bottom of how that could happen, if you are indeed starting your CWD command with “CWD /” + path then it’s concerning, but if you’re some how building the “/” from something that is failing on the client then you’ll need to work around that somehow.

You can install an FTP server on your local machine for testing, a quick google returns https://osxdaily.com/2018/08/07/get-install-ftp-mac-os/ but might be a little overwhelming setting all that up without the UI that the server edition provides. It might be more convenient to install mac os server in a VM on your machine and use that for testing.

Again, without knowing what your FTP client does, or how it works, I’m a bit limited in providing any further info on the problem, sorry.

@: thank you for answering!

Yes, I came to the same conclusion.

Since I did not have any clue on what was happening, I made a wild guess: since the reviewer was accessing a local server, I assumed that the directories he accessed were on his machine; therefore, after getting the initial LIST (cfr. the log he sent me), when he double-clicked a directory in the list (by which the " executeCWD" method below gets triggered), if that directory had no permission, the sandbox environment would block it, and who knows, maybe create a nil path. As I said, a wild guess.

I made a lot of tests, sending to executeCWD a nil path, a " " path, a made-up non existing path “hello”, and the app always answered in the expected way, for instance raising error 550. But never error 500.
When manually sending a nil path, the path was checked and if necessary corrected to “/”.
Yet I must be objective, so I cannot escape/deny the fact that the log clearly shows no “/”. So, in the executeCWD method (below) I added another check: if mPath = “” then mPath = “/”

And of course, in the error method, I added a slot for error 500 so that the user gets some explanation about the vague error.

Now what remains to be seen is what happens submitting the new binary to MAS. Meantime, in the Meta > Description I explicitly added a polite warning that the app is intended for remote servers only.

Thank you very much for the detailed explanation and infos. Much appreciated.

Public Sub executeCWD(mPath as String) if mPath = "" then mPath = "/" write "CWD " + mPath + EndOfLine.Windows End Sub