Summary

  • RFC 9111 requires a cache that sees a non-error response to an unsafe request to invalidate the target URI, but the rule applies to caches through which that request travels.
  • Operators claiming a global purge need separate evidence for cache-path coverage, related URI identities and application-specific derived keys.

Imagine a deliberately hypothetical incident. A client sends a PUT, the origin returns 204 No Content, and a dashboard immediately labels the purge global. The write path crosses an application cache and one regional gateway. A different edge, outside that request path, continues serving a collection assembled from the old object. Nothing in the successful status alone identifies that untouched edge or the derived collection key.

This is not a defect in HTTP caching. It is a boundary between a protocol rule and an operational claim. RFC 9110 calls a method safe when its defined semantics are essentially read-only, and identifies GET, HEAD, OPTIONS and TRACE as safe. State-changing methods are therefore handled differently by caches. RFC 9111 says a cache must write an unsafe request through to the origin: it may not manufacture the response before forwarding the request and receiving the corresponding reply.

The reply then triggers a precise invalidation duty. When the cache receives a non-error response to an unsafe method, it must invalidate the target URI. Here, non-error means a 2xx or 3xx status. Invalidation can remove matching stored responses or mark them invalid so that they require mandatory validation before reuse. The rule is about making an existing stored response unusable without a fresh check; it is not a declaration that every copy everywhere has disappeared.

RFC 9111 also permits a cache to invalidate other URIs. Location and Content-Location values are possible candidates when their origin matches that of the target URI. This permission matters, but it is not a universal dependency-discovery mechanism. A cache must not use the rule to invalidate a candidate URI on another origin, and it is not required to infer every product page, list view, search result, surrogate key or precomputed fragment that an application might derive from the changed object.

The scope is narrower still in topology. The specification explicitly observes that this mechanism cannot guarantee global invalidation. A state-changing request affects stored responses only in caches through which it travels. A cache on a read path that did not carry the write has received no protocol event from which to perform this local duty. Multi-CDN routing, shield bypasses, regional partitions and separate API and page-cache paths turn that fact into an operational control problem.

The mistake is to collapse three different statements into one. “The origin accepted the write” concerns the state-changing response. “A traversed cache invalidated the target URI” concerns a local cache action required by the protocol. “Every reader will now observe the new application state” concerns topology, key derivation and verification across all relevant serving paths. The first statement does not automatically prove the second at every tier, and neither proves the third.

An operator can close the gap with an invalidation-path receipt. This is an editorial control construct proposed here, not an object defined by the IETF. It should bind the unsafe request and its response to the cache instances known to have carried it; record the normalized target URI each instance invalidated; distinguish mandatory target invalidation from optional Location or Content-Location handling; attach the application’s mapping from the changed object to collection, search, fragment and surrogate keys; and store cache-bypassed probes from each material serving path.

The receipt changes the question asked after a successful write. Instead of treating 204 as a global cache event, the operator asks which path carried the write, which cache acted, which identities were covered, and which independent reads demonstrated the new state. That is the point where a protocol-compliant local action becomes evidence for a system-wide assertion.

Sources