| Internet-Draft | Calculating Internet Checksum | October 2026 |
| Yourtchenko | Expires 29 April 2027 | [Page] |
Over the past four decades, the Internet checksum has been used by many protocols: IPv4, TCP, UDP, and others. The practical details related to calculation and updates are scattered across different RFCs. Several protocols introduce special-case handling for +0 and -0, thus making the term "Internet checksum" ambiguous. This affects any protocol implementation which modifies the data covered by any variant of the Internet checksum. This document provides the problem statement and outlines the scope for potential future work to build a consolidated source for the Internet checksum. If there is interest in such work, this document may be converted into that consolidated specification.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 29 April 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The Internet checksum computation was described in detail in [RFC1071] 38 years ago as a 1's complement of the 16-bit 1's complement sum of all 16-bit words over the range the checksum covers, with the checksum field itself set to all-zero. The same document also defined the process of checksum verification being 1's complement sum across the area, the checksum field included. If the result is 0xffff (-0 in 1's complement arithmetic), the check is successful.¶
Intermediate nodes, like routers, often need to update the fields covered by the checksum, and recomputing it from scratch every time is inefficient. Thus, the original document also describes the incremental checksum update mechanism. The initial formulation did not lend itself to efficient implementation. To address that, [RFC1141] described a streamlined incremental checksum update process. However, the process described there can yield an updated header checksum of -0 (0xffff) when it should be +0 (0x0000). [RFC1624] corrected this, but it was ambiguous in places. This resulted in an erratum, which was itself incorrect and triggered additional errata.¶
1's complement arithmetic has two representations of zero, +0 (0x0000) and -0 (0xffff), and this redundancy resulted in some protocols treating these values differently. For example, a correct IPv4 sender never computes a header checksum of -0 (0xffff) by construction, whereas UDP uses 0x0000 as a signal "checksum not computed", and requires the computed checksum of zero to be transmitted as 0xffff. Additionally, the rules for when the checksum computation can be skipped are different between UDP-over-IPv4 and UDP-over-IPv6: the latter allows it only for the outer UDP header of the tunneled traffic [RFC6935], [RFC6936]. The rules in [RFC1624] do not take these special cases into account, thus resulting in subtle bugs even in recent code.¶
Some protocols opted to either make their updates checksum-neutral (e.g. [RFC6296], [RFC6052]), or allocate a "sacrificial field" whose sole purpose is to be updated when another part of the checksum-covered area changes ([RFC7820], [RFC7821], [RFC9197]). This is a useful design technique if the header layout is still open. It may also improve performance: the "sacrificial" checksum correction field can be placed next to the fields which have to be modified, and thus end up already in the processor cache. Also, some protocols opted to use entirely different checksum mechanisms.¶
This document does not redefine any of the existing protocols.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
Taking the above into account, and in stubborn defiance of the wisdom in [XKCD927], this document proposes to be a single reference for all matters related to the Internet checksum, collecting the various aspects of it into the following sections:¶
[RFC1071] covers this at length, but a shorter version, focusing on incremental update and the +0/-0 properties, would be useful. This section would discuss how to verify the checksum, and why recalculating the checksum and comparing it with the received one can result in occasional spurious packet drops.¶
A correct IPv4 sender never transmits 0xffff as its header checksum; UDP never transmits 0x0000 unless the checksum is disabled; UDP over IPv6 permits a zero checksum only when it is the outer protocol for tunneled traffic. Handling these special cases is a frequent source of bugs. This section would contrast how different protocols use the Internet checksum.¶
This section would refer to some of the available open source implementations as well as analyze the issues related to them.¶
It would also demonstrate branch-free approaches to dealing with special-case values during the checksum calculation.¶
During protocol design, it might make sense to make any updates unnecessary by making the transformation checksum-neutral. This section would survey the existing protocols that make use of two techniques for this: defining the transform to be checksum-neutral, or allocating a special field so that a variable transform stays checksum-neutral.¶
This section would include various examples and corner-case test vectors, intended to help verify the implementations.¶
The document does not (yet) have any security considerations.¶
This document has no IANA actions.¶
Thanks a lot to Martin Thomson for the inspiration to write this document and to Tim Chown for reviewing the pre-00 version.¶