Summary
- Telnet's Network Virtual Terminal gave unlike systems a small common action vocabulary:
CR LFfor a new line,CR NULfor carriage return alone, and no bareCRin default NVT ASCII. - The byte after CR was evidence for a two-way decision. The sender chose an NVT action; the receiver translated that action into its own terminal and operating-system conventions.
- RFC 1123 later repaired ambiguity around the human Enter key, while negotiated binary mode disabled line-ending conversion and Net-Unicode retained CRLF but discouraged CR NUL.
A decision deferred by one byte
Imagine the Network Virtual Terminal literally for a moment. Its printer is halfway across a line. Octet 13 arrives: carriage return. In the NVT model, CR moves the print position to the left margin without moving vertically. Octet 10, line feed, moves to the next line while preserving the horizontal position. Together they mean something stronger and more convenient: the left edge of the next line.
Many real terminals did not implement those motions independently. Some coupled Return to a line advance. Some hosts used LF as their local record separator. Others used CR, a pair, a counted record or another convention. If a receiver executed CR immediately, it might then execute LF separately and produce a different result from the intended single new-line action. If it waited, it needed a bounded way to learn whether a second motion was coming.
RFC 318 described the answer in 1972. The receiver could hold CR and examine the next character. CR LF closed the branch as a new line. A CR that was not part of that pair should travel as CR NUL. NUL performed no printer action, but its presence made the sender's choice complete.
The null byte was therefore not a universal blank and not a loose delay character. In this exact grammar position, it was evidence that no LF belonged to the CR.
The imaginary terminal kept the common layer thin
RFC 854 made the Network Virtual Terminal the default intermediate representation for Telnet. A new connection did not begin by exchanging exhaustive descriptions of two terminals. Each host mapped its local device or process into a deliberately modest NVT and assumed the peer would do the reverse.
That allocation of work mattered. The shared protocol defined a few actions. NUL was no operation. LF moved down without changing horizontal position. CR moved to the left margin of the current line. Local code still owned character conversion, terminal timing, physical width, page length and the relationship between a network action and an operating-system interface.
For the combined case, RFC 854 tightened the earlier recommendation into a rule. CR LF had to be treated as one new-line character whenever the combined action was intended. CR NUL had to represent carriage return alone. CR had to be avoided elsewhere in default NVT ASCII. The rule applied in both directions, even when an implementation believed no literal printer was involved.
On receipt, the NUL following CR was stripped before mapping the NVT action to the local character set. It belonged to the network representation, not automatically to the application payload. That distinction is easy to lose when a byte stream passes through several libraries.
Syntax did not decide what the Enter key meant
The wire grammar was precise, yet a human key created another layer of uncertainty. What should a User Telnet send when someone pressed Return or Enter? Was that a request for the NVT new-line function, or a request to transmit the local CR key faithfully?
RFC 1123 recorded the practical split. Some clients sent CR LF; others sent CR NUL. The base specification had described printer output more clearly than terminal input. Implementations made different, defensible readings, and the result became a continuing interoperability problem.
The host requirements repaired the boundary by naming roles and contexts. A User Telnet had to be able to send CR LF, CR NUL and LF. An ASCII client should offer a user-selectable CR LF/CR NUL mode and should default the end-of-line key to CR LF. An ASCII Server Telnet had to make both CR LF and CR NUL have the effect of pressing the local end-of-line key when received as terminal input.
That last rule looks as though it collapses the distinction, but only at a specified interface. In a raw terminal mode the server could pass CR to the application; in a formatted mode it could apply the local line convention. A non-ASCII host still faced a genuine tension between preserving a bare carriage return and accepting the form emitted by existing clients.
For traffic that was not terminal-to-computer input—server output or another application protocol carried through Telnet—RFC 1123 required CR LF for end of line. The same octets could therefore be governed by different translation duties depending on direction and purpose.
Binary was a change of interpreter, not a larger alphabet
It is tempting to treat Telnet's Binary option as NVT with an eighth data bit. That misses the control boundary. RFC 856 made binary transmission a negotiated state for each direction. One side requested it; the other acknowledged it. The opposite direction did not change automatically.
Inside that state, ordinary octets were eight-bit data. Telnet command syntax still survived: IAC introduced commands, and a data byte equal to IAC had to be doubled. But end-of-line conversion stopped. RFC 1123 explicitly forbade replacing CR with CR NUL or CR LF in binary mode.
The negotiated mode decides which interpreter owns the byte. In NVT ASCII, CR begins a two-byte line/action decision. In binary mode, CR, LF and NUL remain data unless application semantics say otherwise. Dropping the NUL merely because it follows CR would corrupt the binary stream. Adding one would do the same.
This is why logging only printable text is insufficient. An operator investigating a line-ending defect needs the octets, the direction and the option state at that point in the stream.
Linemode moved editing without moving output responsibility
RFC 1184 addressed a different cost. Character-at-a-time interaction was painful across long-delay links and expensive on networks charged per packet. Linemode allowed a client to edit locally and send a completed command line rather than make every keystroke wait for a remote echo.
The option did not discard the NVT distinction. With Linemode editing active, a normal local line terminator was sent as CR LF. With editing off, carriage return was sent as CR NUL, LF as LF, and a special key meaning “line complete” as CR LF.
Server output remained the server's responsibility in every mode: CR LF for newline, CR NUL for carriage return alone and LF for line feed alone. Editing authority could move closer to the human without allowing the client to invent the meaning of server output.
This separation is a useful design clue. Placement and semantics are different questions. A system may relocate buffering or editing for latency reasons while keeping the canonical representation stable at the boundary.
The old printer survived inside network text
The NVT printer can feel like an antique metaphor, but its line-ending choice spread far beyond one remote-login session. Early Internet text protocols repeatedly relied on a network form that separated local storage from wire representation.
RFC 5198 revisited that history while defining Net-Unicode. It retained CRLF as the line-ending form for network text and preserved the structural requirement that CR be followed by LF or NUL. Yet it discouraged CR NUL. Modern character composition and markup made many printer-motion tricks unnecessary, and NUL is hazardous in software that treats it as a string terminator.
That is not evidence that the 1972 choice was foolish. It shows a mechanism aging honestly. CR NUL solved a real question when carriage motion was part of the shared abstraction. Later text formats kept the installed line boundary while narrowing the exceptional form whose original use had faded.
The IANA Telnet Options registry still records Binary Transmission, Linemode, carriage-return disposition and later character-set options. The registry proves that the vocabulary has stable names. It says nothing about how many current devices implement them correctly.
A small grammar carried a constitutional idea
Telnet's solution did not appoint one host to dictate how every terminal should work. It placed only the interoperable distinction in the common layer. The sender selected one of two NVT actions. The receiver could validate that selection locally by reading the next byte. Each side retained authority over its own device mapping.
The costly failures came from crossing those boundaries. A client that mapped Enter too early erased a possible bare CR. A gateway that normalized CR NUL without checking option state corrupted binary data. A receiver that acted on CR before its companion arrived guessed when the protocol had promised evidence. A library that treated NUL as the end of a string truncated the very sequence meant to remove ambiguity.
The lesson is larger than line endings. When one symbol cannot carry enough meaning, the protocol should add a finite discriminator and say which layer consumes it. Compatibility becomes fragile when convention substitutes for that explicit state.
Sources and evidence limits
- https://www.rfc-editor.org/rfc/rfc318.html
- https://www.rfc-editor.org/rfc/rfc854.html
- https://www.rfc-editor.org/rfc/rfc856.html
- https://www.rfc-editor.org/rfc/rfc1123.html
- https://www.rfc-editor.org/rfc/rfc1184.html
- https://www.rfc-editor.org/rfc/rfc5198.html
- https://www.iana.org/assignments/telnet-options/telnet-options.xhtml
These sources establish the protocol model, historical rule, host-requirements clarification, negotiated exceptions and registered option vocabulary. They do not measure current Telnet use, certify a product's defaults or establish that every historical implementation behaved alike. The article therefore treats CR NUL as a scoped representation rule, not as a universal property of text.
Member Briefing
Deeper Profile Context
Sign in with the right membership level to unlock the full briefing and source notes.
Only for Strategic Circle
Strategic Circle
Open to all readers. Unlock profile briefings after joining and signing in.
Join Strategic CircleOnly for Leadership Alliance
Leadership Alliance
For qualified IP-asset owners and management; sign in to unlock alliance briefings.
Join Leadership Alliance
