Transfer behavior

Upload without exposing partial files

Use temporary names, completion checks, renames, and independent hashes to make uploads safer.

I never upload straight to the public filename. Another process might read the file while bytes are still arriving. A CDN can cache a half-empty zip. Upload to a temporary name, wait for 226, then rename.

Cron jobs, sync daemons, and download pages do not wait for you to finish typing. They poll the public name. Picture a truncated zip sitting under the final name for an hour while people download it.

Partners sometimes poll every minute. A half-uploaded release.zip is worse than a late release because it looks finished. Rename is the publish step, not put. I never skip the hash check on the final name.

Here is the sequence I use:

ftp> put release.zip release-20260730.part
150 Opening data connection
226 Transfer complete
ftp> rename release-20260730.part release.zip
350 Ready for destination name
250 Rename successful

The 226 tells you the bytes landed. The 250 tells you the rename worked. Check both before you tell anyone the release is live.

Pick a temp name that will not collide with another uploader. I include a date or random suffix, not just .part on everything. Clean old temp files on a schedule you actually run.

When integrity matters, compare a hash out of band:

shasum -a 256 release.zip

Get the expected digest from your CI log or a signed email, not from a .sha256 file sitting on the same FTP folder.

If rename fails after a good 226:

ftp> rename release-20260730.part release.zip
550 File exists

The full file still sits under the temp name. Look there before you delete anything or start over. That saved me once when a partner panicked.

Pull the network cable during put on a test server. Confirm release.zip never showed up while the .part file did.

Lesson completed