An FTP client can accept a put command long before the server has received the file, and the gap between those two events is where most upload mysteries live. Four stages have to complete: the local file is read, the server accepts the storage request, the data connection carries the bytes, and the transfer reaches a final positive reply. Comparing the stages is more useful than comparing clients, because a login that works and a filename that appears both stop short of the finish.

Preliminary reply vs final reply

For STOR, a 125 or 150 reply is preliminary. It says the server is willing to try and that a data connection is opening, not that the object exists in its final form. The operation is complete only when the transfer reaches a positive completion reply, commonly 226 or 250, in that operation's context.

A 426 means the transfer was aborted, and a number printed by another command is not this upload's result. Read the reply that belongs to the STOR, not the last number on the screen. If the client exits before that reply arrives, you have no completion evidence at all.

Control connection vs data connection

Authentication and directory listing use the control connection. The bytes use a separate data connection, and its endpoint is negotiated per transfer. A successful login proves the control path and says nothing about whether the data address is reachable from the client.

When the server cannot open the data connection, investigate the negotiated endpoint and the permitted path. Passive mode still requires a usable data address and port, and a firewall or NAT device between client and server can allow the control session while blocking the data range. When the server rejects the storage request instead, look at the remote pathname, permissions, or storage limits. Neither branch is explained by the control connection having authenticated.

FTP over TLS vs SFTP

FTP over TLS is still FTP: two connections, FTP replies, and a TLS upgrade on each. SFTP is an SSH subsystem with a single connection and a completely different command set. They share a purpose and almost nothing else, so a diagnosis that crosses between them usually starts by comparing the wrong logs.

Do not disable TLS to let an intermediate helper inspect the session, and do not treat an SFTP failure as an FTP reply problem. The curl manual documents explicit TLS, passive mode, and upload options if you need a scripted test, and it is the reference for what each flag actually changes.

Choose the protocol the service actually offers before you debug it. A server that speaks only SFTP will never produce a 226 reply, no matter how the client is configured.

A visible filename vs a stored object

A visible filename can represent an incomplete object, especially after an aborted transfer or a client that exited early. Ask the service's owner to compare the intended test file's size and trusted content hash with the stored object when byte preservation is expected.

Binary and ASCII modes are another comparison that changes the result. ASCII mode can translate line endings, so the stored bytes differ from the local file even though the transfer succeeded. Keep binary mode for a byte-for-byte check, and do not add conversion options to make a failed transfer look different.

An ordinary STOR can replace an existing file, and permission to log in or list a directory does not establish permission to create or replace an object in it. Use a previously unused remote name for the test.

What to compare before retrying

Do not blindly append, resume, or repeat an upload over an uncertain partial file. Agree with the owner whether to restart under a fresh name, use the service's supported recovery procedure, or remove the failed test object.

Write the outcome as one of four statements: the local read failed, storage was refused, the data transfer aborted, or the transfer completed and the stored bytes matched. That record is a stronger result than changing the shell, the VPN, and the FTP settings together until a filename appears, and it tells the next person which stage to inspect. Keep the sanitized reply text with that statement. Then a retry is a decision, not a reflex.

Barruulee wal qabatan