Summary

  • RFC 9111 tells a response carrying must-understand to carry no-store as well. A cache that does not know the new directive ignores it and still receives the conservative old instruction; a cache that implements it can consider the exception.
  • The exception is not triggered by recognizing the words. The cache must recognize the response status code and implement all of that code's caching-related requirements. Status knowledge, directive support and storage eligibility are separate facts.
  • Ignoring no-store removes only one barrier. Method rules, authorization, shared-cache restrictions, explicit cacheability, freshness and later reuse still have to be satisfied. The pair grants neither privacy nor a general licence to retain a response.

The quiet half of an upgrade

A response arrives at two caches:

Cache-Control: must-understand, no-store

The first cache predates must-understand. HTTP's extension rule tells it to ignore a cache directive it does not recognize. That sounds permissive until the second directive is read. The cache does know no-store, so it does not store the response.

The second cache implements must-understand. It also recognizes the response status code and has implemented every caching requirement defined for that code. RFC 9111 says such a cache should ignore the accompanying no-store. It can then evaluate the response under the remaining caching rules.

This is a compact example of protocol evolution without a synchronized fleet upgrade. The new directive opens a capability-specific branch. The old directive preserves conservative behavior for recipients that cannot enter that branch. An origin does not need to identify every cache on the path, and a cache does not need permission from a central service on every response.

The design fails when documentation quotes only the dramatic word. must-understand sounds like a command to every intermediary. It cannot be one. A cache that has never heard of it is required to ignore it. The meaningful rollout unit is therefore the pair, and the meaningful proof is not that the header was parsed. It is that the cache qualifies for the new branch.

“Understood” describes behavior, not vocabulary

RFC 9111 gives “understood” an unusually useful definition. A cache understands a response status code when it recognizes the code and implements all specified caching-related behavior. Each part matters.

A parser can recognize three digits. A library can map those digits to a reason phrase. A generic HTTP recipient can fall back to the status class when it sees an unknown code. None of those facts demonstrates that the cache applies the code's particular storage requirements.

The contrast is visible in the standards. RFC 6585 defines several additional statuses and says responses with 428, 429, 431 and 511 must not be stored by a cache. RFC 7538 defines 308 Permanent Redirect as cacheable by default unless method semantics or explicit cache controls say otherwise. The important point is not to memorize those examples as a complete catalogue. It is that status codes can carry different caching instructions.

Suppose a cache labels 429 as “Too Many Requests” but stores it as if it were an ordinary cacheable response. It recognizes the code; it has not implemented its caching-related behavior. In RFC 9111's terms, it has not understood the status for the purpose of must-understand. A feature flag named supports_must_understand would overstate the evidence if its test checked only directive parsing.

A defensible implementation record needs at least five separate states: the response status; recognition of that status; implementation of its caching rules; implementation of the must-understand directive; and satisfaction of the ordinary conditions that remain after the exception. Conflating those states turns conditional interoperability into self-certification.

Why no-store travels with the new directive

HTTP caches must ignore unrecognized cache directives. Without that rule, every extension could break deployed software. With it, a behavioral extension needs an older instruction that unaware recipients can follow. RFC 9111 describes the pattern directly: send the new directive and the old directive together; unaware caches follow the old behavior, while aware caches treat the new directive as a modifier.

For must-understand, no-store is that older instruction. Its presence does not contradict the new directive. It creates the safe default. The old cache sees a rule it can enforce. The qualifying new cache sees both and knows the narrow condition under which the old rule should yield.

That makes omission consequential. Sending only must-understand asks an old cache to ignore the sole signal intended to restrict storage. The cache may still decline to store for another reason, but the extension has supplied no conservative fallback. Conversely, sending both directives does not guarantee that every old or malicious implementation will behave. Standards conformance is not remote control. It establishes what a conforming participant should do and what an operator can test.

Normative language also deserves care. RFC 9111 says the response SHOULD include no-store, and the qualified cache SHOULD ignore it when the status requirements are understood and implemented. “Should” is not decorative, but neither is it the unconditional “must” that loose summaries often imply. A departure needs a reason grounded in the protocol and the deployment, not merely a preference for shorter headers.

The exception is not automatic cacheability

The most damaging shortcut is to read “ignore no-store” as “store this response.” Those statements are not equivalent.

Section 3 of RFC 9111 sets multiple conditions for storage. The request method has to permit it. The response status has to be final. Special cases such as 206 and 304 require understanding. Authorization and shared-cache rules can apply. A shared cache must respect private. The response also needs an explicit or status-defined basis for cacheability. Other extensions may modify the outcome.

Later reuse is another decision. A stored response needs to match the request and satisfy freshness, validation or an applicable permission to serve stale content. must-understand does not make an object fresh, validate it, select the right cache key, or authorize reuse across users.

The correct mental model is subtraction, not promotion. A qualifying cache subtracts the companion no-store prohibition from the list. It does not erase the list. If any remaining condition fails, the response still cannot be stored. If it is stored but cannot be reused for a later request, storage did not create a reusable answer.

This distinction belongs in observability. A log entry saying must_understand=accepted is too coarse. It should say which status definition was evaluated, which implementation capability supported the conclusion, which remaining storage conditions passed, whether the response was stored, and separately whether it was later reused.

Registry entries are coordinates, not capability proofs

IANA maintains registries for HTTP status codes and cache directives. The directive registry lists must-understand and no-store separately and points to RFC 9111. The status registry identifies codes and their defining documents. These are essential shared coordinates: they reduce naming collisions and lead implementers to the applicable specification.

They do not attest to software. A binary does not become conforming because a token appears in an IANA table. A package manifest that claims RFC 9111 support is not proof that every newer status module is present. Even a successful test for one status does not establish support for all future statuses.

The status definition is therefore part of the executable dependency graph. Introducing a status with distinctive caching behavior requires the cache's status module, test cases and upgrade evidence to travel together. must-understand supplies the protocol hook for that proof; it does not manufacture the proof.

RFC 9111's change log says must-understand was introduced so caches need not understand new response status semantics unless the directive is present. That gives origins a way to say, in effect, “the special status rules matter to caching this response.” It does not give them a way to declare an unknown cache competent from afar.

It is not a privacy control

no-store has a deliberately limited security claim. RFC 9111 says it is not a reliable or sufficient mechanism for privacy. A malicious or compromised cache can disregard it, and the network can expose the communication by other means. The must-understand pairing does not enlarge that promise.

Nor does the pair determine who is authorized to receive a response, whether a shared cache partitions users correctly, whether transport is confidential, or whether a stored representation remains protected at rest. Those controls live elsewhere. Treating the header as a data-classification seal risks weakening the systems that actually enforce access and retention.

The same boundary applies to operational assertions. This research did not test a cache vendor, measure support, observe a storage leak or estimate adoption. Examples here are standards-derived thought experiments. A production claim requires production evidence.

Sources and evidence boundary

The source set establishes protocol semantics and the governance lens. Registry and errata observations are snapshots at the research cutoff. No claim of universal implementation support, observed incident frequency or vendor conformance is made.