Summary

  • IPv4 protected only the header its routers had to read and change. Each processing point could verify that header, decrement TTL or alter other permitted fields, and renew the checksum without claiming that the payload or original path was intact.
  • TCP and UDP used the same one's-complement arithmetic across transport bytes and a pseudoheader containing selected IP facts. That wider scope helped catch misdelivery, but it was still consistency evidence—not authentication, ownership or proof that no deliberate modifier had recomputed the value.
  • The arithmetic had two zeros. RFC 1141's fast incremental formula could produce 0xFFFF where full IPv4 header recomputation produced 0x0000; RFC 1624 corrected the boundary. IPv6 later removed the base-header checksum while keeping upper layers responsible for what they depended on.

A header that could not remain still

The IPv4 header was never an immutable envelope. A sender placed a Time to Live value in it; every Internet module that processed the datagram reduced that value by at least one. Fragmentation could change total length, flags and offsets. Options could also be modified in the cases the protocol allowed. A router therefore received a header, relied on it, and then legitimately changed it before forwarding.

That is the setting in which RFC 791 defined the Internet header checksum. The field is the 16-bit one's complement of the one's-complement sum of every 16-bit word in the header, with the checksum field itself treated as zero during calculation. It is explicitly a checksum “on the header only.” When a changing field such as TTL is updated, the value is verified and recomputed at the processing point.

The sequence matters. A router is not preserving a sealed assertion created by the source. It tests whether the header it received is arithmetically consistent, makes an authorized local mutation, and emits a fresh assertion about the new header. The claim lives for one version of one header between processing boundaries.

RFC 791 also states what is absent. IP supplies no acknowledgments, no retransmission and no data error control; a failed header checksum leads to immediate discard, but a passing IPv4 header checksum says nothing about the payload. Reliability belongs elsewhere. The field protects the information the Internet layer needs in order to process the datagram, not everything the datagram might mean.

Three checks with three different borders

It is tempting to speak of “the Internet checksum” as a single blanket around a packet. The early specifications instead draw three borders.

IPv4 checks its own header. RFC 768 makes UDP's checksum cover the UDP header and data, plus a conceptual pseudoheader. RFC 793 makes TCP's checksum cover the TCP header and text, also plus a pseudoheader. The arithmetic is related; the evidence is not interchangeable.

This separation prevented a mutable Internet-layer field from forcing an end-to-end transport checksum change at every hop. TTL can fall while the TCP or UDP bytes remain constant. The router renews the IPv4 header checksum; endpoints retain responsibility for the transport calculation. A link technology may add another error-detection field around the frame, but that field has yet another lifetime and coverage boundary.

The design is a stack of finite statements. A link check may say that one frame arrived consistently over one adjacency. An IPv4 header check may say that the current network-layer control fields agree with their 16-bit sum. A transport check may say that the endpoint-visible segment and selected addressing facts agree. None becomes stronger merely because the same packet passed all three.

A header that was never sent

The transport pseudoheader is one of the Internet's most useful fictional objects. UDP conceptually prefixes source address, destination address, protocol and UDP length to the material it sums. TCP uses a 96-bit IPv4 pseudoheader with source, destination, protocol and TCP length. Those bytes are inputs to the calculation, but the pseudoheader is not transmitted as a separate transport header.

Its purpose is precise. RFC 768 and RFC 793 say it gives protection against misrouted datagrams or segments. A TCP segment delivered under different source or destination addresses should not casually validate merely because its own TCP bytes survived. The calculation binds the transport material to the network-layer endpoints and protocol number on which delivery depends.

But “binds” is not “authenticates.” A sender that can construct the packet can construct the checksum. An intermediary deliberately changing both covered bytes and the field can recompute it. The pseudoheader does not certify who controls an address, whether a registry record is accurate, whether routing policy was lawful, or whether the path avoided interception. It makes certain accidental mismatches observable at the receiving endpoint.

The fiction is valuable because it crosses a layer boundary without merging the layers. IP still transports a datagram. TCP and UDP still own their verification result. Selected IP facts enter the transport calculation because the transport depends on them, not because the transport protocol acquires authority over routing.

UDP needed both zeros

One's-complement arithmetic has a property that modern intuition often resists: zero has two representations. Sixteen zero bits form positive zero, 0x0000. Sixteen one bits form negative zero, 0xFFFF. In arithmetic they can be equivalent; on a protocol wire they can carry different meanings.

RFC 768 uses that distinction deliberately. If the computed UDP checksum equals zero, the sender transmits all ones. An all-zero UDP checksum field means that the sender generated no checksum. Thus 0xFFFF can be the valid result of checking, while 0x0000 can announce that checking was omitted under the original IPv4 UDP contract.

The special case prevents a receiver from confusing a genuine arithmetic result with an opt-out signal. It also demonstrates that canonical encoding is part of semantics. An implementation cannot collapse the representations merely because its programming language considers both values equivalent after a particular operation.

IPv6 later narrows the escape. RFC 8200 requires UDP checksums by default: a computed zero is placed on the wire as 0xFFFF, and a receiver must discard an all-zero UDP checksum. A bounded exception exists for specified UDP tunnel encapsulations subject to additional requirements; it is not a general return to optional verification.

The arithmetic that could be rearranged

Cheap verification mattered on machines that could not spend freely on every packet. RFC 1071 explains why one's-complement addition could be made fast without changing the shared answer.

With the even and odd byte positions respected, the sum is commutative and associative. An implementation may split a buffer into groups, add partial results and combine them later. It may calculate in either byte order and swap the final result as needed. Wider accumulators can postpone carry folding; parallel paths and machine-specific instructions can do more work per loop. When the byte count is odd, a zero pad completes the last word for calculation but is not transmitted.

This was a kind of implementation federalism. The protocol fixed the wire result and the coverage; it did not legislate one loop for every processor. A PDP-11, a large machine and a later router could exploit different local capabilities while remaining interoperable.

The freedom was conditional. Reordering bytes without preserving parity changes the words. Dropping the final odd octet changes the input. Mishandling end-around carry changes the algebra. Optimization was legitimate only when it reproduced the exact common result, including the cases that ordinary test traffic rarely reached.

Updating one word instead of the whole header

A router decrementing TTL already knows which 16-bit word changed. Resumming the complete IPv4 header is possible, but the checksum's algebra allows a smaller operation: remove the old word's contribution, add the new word's contribution, and fold the carry.

RFC 1141 made the operational benefit concrete. In the common TTL update, subtracting one from TTL means adding 1 or 256 to the stored checksum, depending on the byte position, using one's-complement addition. RFC 1624 lists TTL changes, fragmentation and source-route changes among the routine uses of incremental computation.

The optimization keeps cost proportional to change. A router does not need to revisit stable source and destination fields merely because one small mutable field advanced. That helped preserve a per-hop integrity check without making every forwarding decision pay the cost of full header summation.

It also moved correctness into an equation. Full recomputation has a clear reference meaning: sum the revised header and complement the result. Incremental computation must be exactly equivalent across every old checksum, old field and new field. “Usually the same” is not interoperability.

The formula that crossed the wrong zero

RFC 1141 improved the practical notation inherited from RFC 1071, but one boundary remained. RFC 1624 reports that the earlier expression could produce a different value from full recomputation because it implicitly used a distributive property that one's-complement arithmetic does not preserve when the result is zero.

The worked example is deliberately ordinary. A 16-bit field changes from 0x5555 to 0x3285; the sum of all other header octets is 0xCD7A. Recomputing the revised header yields a stored checksum of 0x0000. The RFC 1141 method yields 0xFFFF.

Those are not safely interchangeable in an IPv4 header checksum field. RFC 1624 reasons that an IP header has at least one non-zero field. One's-complement addition of non-zero inputs can produce negative zero but not positive zero; after the final complement, the header checksum can contain 0x0000 but cannot legitimately contain 0xFFFF. The previous method created the representation full recomputation could not produce.

The corrected form is HC' = ~(~HC + ~m + m'), with the additions performed in one's-complement arithmetic. It avoids the invalid distributive step and restores equivalence to recalculating the changed header.

Why did the bug not fail everywhere? RFC 1624 notes two verification styles. A receiver following RFC 1071 can include the received checksum in the sum and compare the result with negative zero; in the example, either stored zero representation still leads to the expected final sum. Other implementations recomputed the checksum and compared that value directly with the field. They could reject the non-canonical result.

Product testing exposed the boundary, and simulation helped verify the correction. The episode is not evidence that the checksum was unusable. It is evidence that a shared representation cannot rely on the tolerance of one receiver. The producer must emit the value the protocol's reference computation defines.

IPv6 removed a repeated claim

The IPv6 base header in RFC 8200 has no Internet-layer checksum field. Its fixed header carries version, traffic class, flow label, payload length, next header, hop limit and 128-bit addresses. The omission did not declare packet integrity complete. It changed where the Internet required the calculation.

Upper-layer protocols that depend on IP addresses use an IPv6 pseudoheader with the 128-bit source and final destination, upper-layer length and next-header value. ICMPv6 adds that pseudoheader specifically because, unlike IPv4, the relevant IPv6 fields are not covered by an Internet-layer checksum. TCP and UDP retain endpoint calculations; links may retain their own checks.

The architectural trade is visible. IPv4 made every router verify and renew a small header assertion even though lower layers and upper layers often performed adjacent checks. IPv6 removed that repeated base-header work and left protocols to protect the fields they actually consumed. Corruption in an unprotected dependency remains a risk; duplicate work also has a cost.

This is not a linear march from weak to strong. It is a revision of scope. The Internet kept the one's-complement transport boundary where compatibility and endpoint coverage required it, removed one per-hop boundary from the base header, and strengthened the default rule for UDP.

Sources and uncertainty

RFC 768 defines UDP coverage, the pseudoheader and the two wire zeros. RFC 791 defines IPv4's mutable, header-only check. RFC 793 defines TCP coverage. RFC 1071 records implementation properties. RFC 1141 describes incremental updating. RFC 1624 documents the zero-boundary failure and correction. RFC 8200 shows the IPv6 boundary and its upper-layer rules.

The sources do not establish a lone inventor, one implementation method, current offload prevalence or a universal vendor default. They do not support a numeric claim about undetected errors. A passing checksum cannot distinguish accidental integrity from deliberate recomputation, and a failing one does not by itself identify the link, device or actor that changed the protected material.

The historical fact is narrower and more durable: the Internet made some errors cheaply visible by specifying exactly which bytes entered a common calculation, exactly who renewed it, and exactly where its meaning stopped.