Summary

  • RFC 768 gave the UDP checksum field two distinct meanings for zero: a computed zero was transmitted as 0xFFFF, while a wire value of 0x0000 meant that no checksum had been generated.
  • The 1989 host requirements kept omission possible but made checksum generation the default. IPv6 later made the checksum mandatory, before a 2013 update allowed a narrowly bounded tunnel case.

One field, two zeros

In August 1980, Jon Postel’s RFC 768 specified User Datagram Protocol as a way for applications to exchange datagrams with a minimum of protocol machinery. It did not promise ordered delivery, duplicate protection or reliability. The header was only eight octets: source port, destination port, length and checksum, followed by data.

The last field looks simple until arithmetic gives it an awkward edge. UDP used the 16-bit one’s-complement checksum also used by TCP. Its calculation covered the UDP header and data plus a pseudo-header containing the IP source and destination addresses, protocol number and UDP length. Postel said that pseudo-header helped protect against datagrams delivered to the wrong destination context.

In one’s-complement arithmetic, zero has two bit patterns: all zeroes and all ones. RFC 768 assigned those patterns different jobs on the wire. If calculation produced zero, the sender had to transmit all ones. A transmitted field of all zeroes instead said that the sender had generated no checksum. The packet format therefore carried both a result and a small status signal without adding a flag bit.

That is the article’s narrow historical point. A zero checksum was not a checksum whose calculated value happened to be zero. It was an encoded absence. Confusing those states could cause an implementation to reject a valid datagram, or to treat missing error detection as if it had been verified.

Optional did not mean the default

The original specification left room for omission, describing debugging and higher-level protocols that did not care about the checksum. Nine years later, RFC 1122, the Internet host requirements, made the operating rule clearer. A host had to implement checksum generation and validation; an application could optionally control generation, but it had to default to on. Receivers could optionally choose whether to pass unchecksummed datagrams to applications.

RFC 1122 also called out a common implementation error: computed zero must go on the wire as 65535, while the all-zero field means absent. It reported that some applications used on local-area networks had disabled checksums for efficiency and that numerous undetected errors had been reported. The document supplied no counts, named incidents or denominator, so that passage is evidence of a concern recorded by standards authors, not a measurement of how widespread the practice was.

The checksum was never a signature. Its pseudo-header could catch certain misdeliveries and the calculation could detect some accidental corruption. It could not authenticate the sender, prevent deliberate modification or prove that application data was sensible. “Checksum present” and “packet trustworthy” were different claims.

IPv6 tightened the boundary

The 1998 IPv6 specification, RFC 2460, made UDP checksums mandatory. If the calculated result was zero, it too had to be written as 0xFFFF; a receiver was to discard an IPv6 UDP datagram whose checksum field was zero. This made the previously optional absence marker unacceptable in ordinary IPv6 UDP traffic.

That rule later met a specific performance case. In 2013, RFC 6935 and RFC 6936 updated IPv6 behavior for constrained UDP tunnel encapsulation. Tunnels might carry packets that already had their own integrity checks, and calculating an outer checksum could impose cost. The exception depended on applicability conditions, endpoint behavior and middlebox compatibility; it did not turn zero checksums into a general IPv6 option.

The standards sequence is revealing because the bit pattern stayed the same while the permitted context changed. In IPv4, zero could mark absence, with host guidance defaulting toward calculation. In IPv6, absence was initially rejected, then narrowly restored for a particular outer-tunnel role with additional safeguards. The number alone never told a receiver whether skipping the checksum was acceptable. Protocol version and use context did.

Sources