Summary

  • RFC 9659 requires HTTP zstd decoders to support window sizes through 8 MB and forbids encoders from producing frames that require a larger window.
  • A green canary, a correct registry token or an encoder configuration is not evidence that every served cache variant stayed within that boundary or that every recipient decoded and accepted it.
  • The defensible receipt chain joins the actual frame header to transformation provenance, cache identity, the recipient’s effective limit, the decode result and the application outcome.

The canary request worked. It negotiated zstd, received a short representation, decoded it, and painted the page. On the strength of that result, a fleet dashboard could reasonably turn green. Yet an older cache object may still contain a frame created before the encoder cap changed. A large response can select that object at a different edge, reach a process with a lower effective memory allowance, and fail before the application sees a byte. Both observations can be true: the canary succeeded, and the service remained non-interoperable.

That is the operational importance of RFC 9659. The document is small because the common contract is small. For the HTTP zstd content coding, a decoder MUST support Window_Size values up to and including 8 MB, while an encoder MUST NOT emit a frame that requires more than 8 MB. The rule converts an earlier recommendation into a paired requirement. It does not convert configuration into observation.

Why the window matters

RFC 8878 defines the Zstandard frame format. A frame’s window bounds the distance over which the decoder may need to retain previously produced content for back-references. The format permits values from 1 KB to roughly 3.75 TB. Larger windows can improve compression ratio, but they enlarge the memory commitment a recipient may face.

Before RFC 9659, RFC 8878 recommended that HTTP decoders handle up to 8 MB and that encoders avoid larger windows. Recommendation left a dangerous overlap: one implementation could regard a larger frame as a legitimate optimization, while a browser or constrained agent could reject it to protect memory. RFC 9659 closes that overlap for the zstd HTTP coding. The canonical text and XML source expose the same deliberately narrow change.

The RFC Editor information record identifies RFC 9659 as an Informational IETF document that updates RFC 8878. The errata search and Datatracker history belong beside the deployed rule: operators need to know which stable text, subsequent correction state and publication history their controls claim to implement.

Negotiation is not a decode receipt

RFC 9110 gives HTTP content codings their semantic role. Accept-Encoding: zstd tells a server that the recipient is willing to accept a representation using that coding. Content-Encoding: zstd states which coding was applied to the selected representation. Neither field states the Zstandard window in the served frame. Neither proves which binary created it, whether an intermediary recompressed it, whether the recipient allocated the needed state, or whether the application accepted the decoded content.

The distinction is easy to lose in aggregate telemetry. A server can count negotiated zstd responses without parsing a single emitted frame. An edge can record HTTP 200 before a client attempts decompression. A browser can support the coding while an embedding environment applies a tighter memory limit. A syntactically correct header is a naming event; successful decoding is a later state transition.

RFC 7694 provides another useful boundary. It describes how a server can advertise acceptable content codings for request bodies. That advertisement is also a capability statement, not proof about a particular encoded request or its successful processing. The same discipline should apply in both directions: preserve the offered set, the selected coding, the actual bytes and the result as separate evidence.

A cache can preserve the state the control plane forgot

RFC 9111 makes caches part of HTTP delivery semantics. When compression varies by Accept-Encoding, the selected representation and the cache key must remain aligned. An origin encoder may be corrected while an older compressed variant remains fresh at an edge. An intermediary may decompress and recompress. A purge may cover one key space but miss another. A fallback response can be stored without a sufficiently distinct variant identity.

For RFC 9659 compliance, the relevant object is therefore not “the URL” or “the origin setting.” It is the exact served byte stream and its custody history. A useful record ties a response to the origin build, encoder library, effective window cap, transformation hops, cache key, object generation, frame-header parse, client class and decode outcome. Without that join, separate green signals can describe separate objects.

The IANA HTTP Content Coding Registry now describes zstd as a Zstandard byte stream with Window_Size no greater than 8 MB. Registry language defines what the token means. It cannot inspect a cache object and make the bytes conform. A registry entry is public coordination; a frame capture is operational evidence.

Decoder support and effective budget are different claims

The decoder side of RFC 9659 is deliberately symmetric with the encoder side. Producers cannot demand more than 8 MB; recipients claiming the HTTP coding must handle up to that line. Even so, a library capability test is not identical to an application result. The calling process may impose a lower resource limit, terminate early, encounter allocation pressure, reject the response for a different reason, or fail after decoding during parsing.

This is why a compliance matrix should contain at least three different receipts. The first is a library or user-agent capability statement. The second is the effective limit in the process that handled the response. The third is the observed result for the captured representation. Collapsing them into “client supports zstd” hides the exact place where an interoperability claim can fail.

RFC 9659 also warns that recipients can receive oversized, nonconforming frames and fail decoding them. That is not a contradiction. The decoder requirement establishes support through 8 MB; it does not require unlimited allocation or successful processing of invalid input. Operations should distinguish a standards-boundary rejection from corruption, truncation, unsupported coding, dictionary mismatch, cache poisoning, application parsing failure and general resource exhaustion.

Do not import a different window contract

RFC 9842 later defines Compression Dictionary Transport, including the dcz content coding. Its Zstandard dictionary use can permit a window rule tied to dictionary size, with an upper bound as high as 128 MB. That is an adjacent contract for a different coding. It is not permission to serve ordinary zstd responses above RFC 9659’s 8 MB line.

The distinction matters during feature rollouts. A shared compression library may expose one generic “window” control while different HTTP codings carry different interoperability meanings. Evidence must retain the coding token and the frame context, not merely the library name. A test for dcz cannot certify zstd; a successful zstd canary cannot certify dictionary negotiation.

What a defensible receipt chain contains

At the producer, retain the encoder binary and version, effective configuration, content-coding choice, frame header and object hash. At every transformation boundary, retain whether bytes were passed through, decoded, recompressed or replaced. At the cache, retain variant key, object generation, freshness and invalidation history. At the recipient, retain user-agent or library version, effective memory limit, frame-window observation, decode result and classified error. At the application, retain acceptance rather than inferring it from transport completion.

Sampling can make this practical. Parse frame headers for each encoder build and response class. Compare object hashes across origin and edges. Exercise old and constrained client classes with boundary frames, not only small payloads. Verify that fallback has a distinct cache identity. Alert when observed frames exceed 8 MB, when a transformation has no provenance, when decode failures cluster by object generation, or when negotiation counts diverge from completed application outcomes.

Heng Lu’s Minimum Initial Specification offers the right institutional shape: keep the common contract small enough to implement and audit, while leaving local optimization free inside it. The 8 MB boundary is such a contract. Reality Layers prevents the zstd label from borrowing the authority of a successful decode. Running-Code Primacy assigns the final word to the bytes that were actually served and the recipient that actually processed them.

RFC 9659 resolves an ambiguity that should never have been delegated to guesswork between producer and recipient. Leadership earns the interoperability claim only by showing that the rule survived the whole path.

Sources