Summary

  • Early FTP restart paired sender and receiver checkpoints, including storage and transformation state. REST STREAM later made the marker a transmitted-octet offset.
  • A marker can say where to continue only inside the same transfer context. It does not prove that a pathname still names the same version or that the saved prefix matches it.
  • RFC 3659's worked example verifies that the server file has not changed before resuming. That sentence marks the boundary between bandwidth recovery and object integrity.

The reassuring intermediate reply

Assume an FTP download stops after 802,816 octets. The client reconnects, selects Image type, sends REST 802816, receives a 350 reply and follows with RETR. The transfer continues rather than beginning again.

This looks like a complete recovery protocol. It is not. The 350 reply means that the server saved a restart value for the next transfer command. It does not say that the remote file is the same version, that the local prefix came from it, or that octet 802,817 begins the intended suffix.

The number is useful because other facts are assumed to remain true. Its economy comes from leaving those facts outside the number.

Before the marker became an offset

RFC 765 already treated restart as error recovery. Its REST command did not move file data. It asked the server to position itself at a marker, after which the interrupted service command had to follow.

That marker was deliberately not defined as a universal byte number. FTP connected machines whose files could use different word sizes, character encodings, line conventions and record structures. The protocol separated the logical byte of a stored file from the eight-bit transfer byte. TYPE, STRUcture and MODE jointly determined what appeared on the data connection.

RFC 959 retained this heterogeneous model. Block and Compressed modes could insert distinguishable restart-marker blocks into a formatted data stream. A sender could place enough information in a marker to find its position later; a receiver could correlate that marker with the way it had stored the arriving file.

The design did not require two unlike filesystems to agree on one universal coordinate system. It required each side to recognize its own coordinate again.

One checkpoint, two local meanings

RFC 1123 repaired an error in RFC 959's description of the restart reply. The corrected form paired ssss, a position in the sender's system, with rrrr, the corresponding position in the receiver's system. The encodings could remain implementation-specific because each value would later return to the system that created it.

That pair carried more than progress. Before reporting its side of the checkpoint, the receiver was advised to force all preceding data to stable storage. Otherwise a marker could promise recovery from bytes that disappeared with the same crash that interrupted the transfer.

Transformation state mattered too. RFC 1123 offered a precise example: during TYPE A conversion, a receiver might turn CR LF on the wire into one local LF. If a restart marker arrived between CR and LF, the receiving position had to remember that CR had already been seen and discarded. A bare disk offset could not reconstruct the decoder's state.

The document also defined 554 for a position that could not be restored and 555 for a mismatch between the existing partial file and the current TYPE or STRUcture. Even a syntactically valid marker was conditional.

Stream mode traded opacity for counting

The marker system was capable but heavy. RFC 1123 described restart, ABOR and Block mode as valuable robustness features that were not widely implemented in 1989; REST was not in its minimum FTP command set.

Ordinary Stream mode created a simpler opportunity. Its data connection held unformatted data octets, so an inserted marker would be indistinguishable from file content. RFC 3659 standardized another interpretation: for REST STREAM, the decimal value is the number of octets the next transfer will skip.

The extension had to be discoverable. A server supporting this form announces REST STREAM through FEAT, the feature-negotiation mechanism defined by RFC 2389. A client therefore need not infer support from a brand or a failed experiment.

Counting did not remove representation. RFC 3659 shows one stored text file whose SIZE is 1,830 in TYPE I but 1,942 in TYPE A because line endings acquire extra transmitted octets. The restart number belongs to the stream that would be sent under the selected parameters, not automatically to the local file's native byte layout.

For a resumed upload, that distinction is operational. The client needs to know how much the server correctly received and saved. SIZE can supply the transmitted length under the current TYPE, but it is still a length. It is not a digest of the saved prefix.

A position cannot identify its object

RFC 3659's example is unusually candid. Before resuming at 802,816, it says the previous transfer used TYPE I and that the file on the server has been verified not to have changed.

The verification is not performed by REST. If the pathname now resolves to a different file of sufficient length, the same offset can be accepted and the client can concatenate an old prefix with a new suffix. Equal size does not cure the problem; two versions can have the same length. A successful final reply proves that the requested FTP operation completed, not that the assembled bytes have the identity the operator intended.

Upload restart has sharper limits. RFC 3659 defines it as completion of a previously failed transfer. If the restart point is not at the end of the bytes already stored, or the new data does not extend the object to at least its previous size, effects are undefined. APPE is not a shortcut around that contract; if allowed after REST, it must behave like STOR at the selected position.

Sequencing is part of the state

REST must be the last command before the transfer command. The server can accept the marker with 350 yet reject the following RETR or STOR when it discovers that the position is out of range or cannot be applied. If the transfer command was not successfully sent, a careful client sends REST again rather than assuming the saved value survived unrelated dialogue.

The protocol therefore distributes recovery state across several places: local partial data, the selected representation, server capability, the saved marker, the next command and the identity checks surrounding the pathname. Treating the offset as the whole state machine is the mistake.

Sources and evidence limits

The original checkpoint model is documented in RFC 765; the classic command and transfer modes in RFC 959; the corrected paired-marker and stable-storage procedure in RFC 1123; feature discovery in RFC 2389; and STREAM restart, SIZE, sequencing and examples in RFC 3659. These standards establish semantics, not present deployment share or proof that any particular server preserves versions. FTP restart is not authentication, a content hash, exactly-once transfer or a storage snapshot.