Summary

  • Cache-Status lets each cache report how it handled one response and its request. Its ordered members can distinguish a hit from several kinds of forwarding, validation, storage and request collapse.
  • The report is selective and locally authored. A hit can be stale, TTL is the reporting cache's calculation, most parameters are optional, and list order does not authenticate the caches or prove that the chain is complete.
  • Leaders should treat the field as operational testimony: preserve it, correlate it with caching directives, Age, Via, traces and internal telemetry, and keep authority to disclose, interpret and act separate from authority to deliver the response.

A convincing verdict in one short word

A customer says the price on a product page is wrong. The origin team shows the corrected record. The application team shows a successful deployment. The response observed at the edge carries a compact line:

Cache-Status: EdgeCache; hit; ttl=376

The incident room immediately has a story. The edge served a cached response. It has 376 seconds left. Purge it, blame the cache and close the incident.

Only the first sentence is close to what the field actually says. Under RFC 9211, hit means that this cache did not forward this request and obtained the response from its cache. It does not say that the response was fresh. A stale response served without forwarding can still be a hit. It does not say that the cache key represented the application correctly, that invalidation reached every tier, that the object was authentic, or that the customer saw the intended price. The ttl value is remaining freshness as calculated by that cache, including any heuristic freshness or local configuration it applied.

That narrower statement is not weak. It is exactly the kind of fact an operator needs. The danger begins when the organization promotes it from a statement about one decision at one cache into a verdict about the whole service.

The standard solved a real observability problem

Before Cache-Status, caches commonly emitted proprietary headers with names and values that differed by product. One service might say HIT, another TCP_MEM_HIT, another include an age or node code that only its support team could decode. Tools could collect the strings, but their semantics remained local.

RFC 9211 created a shared vocabulary using HTTP Structured Fields. The value is a list. Each member represents a cache that handled the request. The first member is closest to the origin; the last is closest to the user. A reverse-proxy cache can write first, a shield can preserve that member and append its own, an edge can append another, and even a user agent can add a final member.

This ordered form is operationally powerful. It can show that the origin-side cache had a hit while the edge had a URI miss, or that a forward proxy collapsed several requests and stored the result before a browser cache missed. It replaces a bag of vendor clues with a parseable account.

But the chain is produced by the systems it describes. RFC 9211 says caches decide when it is appropriate to add the field. Some can emit it on every response; others can require configuration or an activating request field. When a cache adds a member, it should preserve the existing value. “Should preserve” is essential choreography, not tamper evidence. A participant can omit a member, strip an earlier value, use a generated identifier or decline to reveal optional parameters. The wire format remains valid even when the evidence is incomplete.

Each member has an author, not an oracle

A Cache-Status member begins with an identifier. The standard allows a product or service name, hostname, IP address or generated string. That flexibility makes deployment possible across public CDNs, private reverse proxies and embedded caches. It also sets a boundary: the identifier is a string asserted in the message. RFC 9211 does not define a certificate, key lookup or challenge that proves the member was written by the legal entity, service instance or host its label suggests.

This matters most when delivery and explanation share an owner. A CDN can serve the bytes and write the account of how it served them. During normal operations, that alignment is convenient. During a commercial dispute, compromise or severe incident, it means the same control plane can affect both the event and the first record of the event.

The correct response is not to distrust every header. It is to classify the evidence accurately. The raw field is direct evidence of what reached a defined observer. It is evidence that the message carried the member. Binding the member to a cache instance requires transport, topology, configuration or cryptographic context. Establishing that the reported internal state was true requires correlation with another observable surface.

A hit is narrower than a green light

The Boolean hit is attractive because dashboards can count it. Its definition is still narrower than most dashboard labels.

A hit says the request was not forwarded and the response came from the cache. A response originally produced by an origin can be modified into a 304 or 206 and remain a hit if this request did not go forward. A response can also be stale and remain a hit when the cache is permitted to use it without forwarding, including some disconnected or failure conditions.

HTTP's cache permissions live elsewhere. RFC 9111 defines when a response may be stored, selected, reused, validated or served stale. Cache-Control, Expires, validators, request directives and extensions such as stale-if-error shape those decisions. Cache-Status reports the outcome of a handling decision; it does not grant permission for that decision.

This is the first governing separation:

  • Cache-Control and related semantics constrain behavior.
  • local configuration and runtime state implement behavior.
  • Cache-Status describes selected parts of the behavior after the decision.
  • user and application checks decide whether the delivered result was acceptable.

If an organization lets “hit” mean all four, it can be correct about the cache transaction and wrong about the service.

Forwarding reasons expose the selection path

When a request goes toward the origin, the fwd parameter can explain why. Its vocabulary is more useful than a generic MISS.

uri-miss says no cached response matched the request URI. vary-miss says there was a URI match but no usable representation matched the request fields selected by stored Vary. request says a fresh cached response was available, but request semantics prevented its use. stale says a selected response required forwarding because it was stale. partial says the cache could not satisfy all requested ranges. method and bypass expose still different control decisions. A generic miss is available where an implementation cannot distinguish more precisely.

Those distinctions change the next action. A surge in URI misses may follow a deployment that altered paths. Vary misses can reveal a new content-negotiation dimension or a fragmented key space. request can point to clients forcing revalidation. stale with next-hop 304 can demonstrate successful validator traffic rather than a full object fetch. bypass can reveal policy scope rather than an empty cache.

The field therefore has decision value precisely when operators resist flattening it. A single hit ratio erases the reason a cache forwarded, the part of the path that did so and the difference between revalidation and object generation.

The optional parameters are different kinds of evidence

fwd-status reports the status returned by the next hop. It is meaningful only when forwarding occurred. If the cache revalidated a stale object and the backend returned 304, the final client response may be 200 while the member records fwd=stale; fwd-status=304. That is evidence of a validator exchange, not proof that the validator represented current business data.

ttl reports remaining freshness lifetime as calculated by the cache close to the time it sends the response fields. It can be negative. It can incorporate heuristic freshness and local policy. It is not a universal expiry timestamp, and it is not interchangeable with Age. Age estimates time since the origin generated or validated the response across cache residence and transit; TTL says how much freshness this cache calculates remains. Investigators need both, along with Date and the controlling directives.

stored reports whether a forwarded response was stored by this cache. It does not promise that the object will remain resident, that another request will select it, or that invalidation will reach it.

collapsed reports whether the request was combined with other forward requests. Successful request collapse can protect an origin from a stampede. It also means one upstream result can fan out to many waiters. A collapse incident is therefore both a performance story and a concentration-of-consequence story.

key can expose a representation of the cache key. That is extraordinarily useful when an application and a cache disagree about query normalization, header variation or tenant boundaries. It is also sensitive. The representation is implementation specific, and the standard's security section warns that revealing key modifications can help cache-poisoning attacks.

detail is deliberately local. detail=MEMORY can mean something useful inside one product, yet the same word from another cache need not mean the same thing. If a meaning must interoperate, it belongs in a registered extension parameter, not in an institutional guess that two identical tokens share semantics.

Most of these parameters are optional. Absence must be read as “this response does not carry the assertion,” not “the event was false.” That small discipline prevents countless false dashboards.

The chain exists only while participants maintain it

Consider a path with an origin cache, a shield, an edge and a browser. The ideal record contains four ordered members. In reality, the browser may never emit Cache-Status, the edge may expose the field only to an authenticated debug request, the shield may use a generated identifier, and a security gateway may remove diagnostic fields before the response reaches the customer.

The list observed by a client is therefore a chain of disclosed accounts, not a discovery protocol for every cache in the path. Via can add evidence about forwarding recipients and protocol versions, but it too has its own intermediary rules and privacy choices. Proxy-Status can describe proxy errors or handling that is broader than caching. Neither field turns the other into a complete topology record.

Operators should test the path they actually run. Send a controlled request through every intended tier. Capture at several observation points. Verify member order, preservation, identifiers and optional parameters. Repeat under hit, URI miss, Vary miss, validation, stale serving, bypass and collapse. Then change one intermediary and repeat. A diagram of expected tiers is not evidence that the response field survives those tiers.

Reported handling is not cache-key authority

The most consequential confusion is between a cache's explanation and the policy that made reuse legitimate.

An HTTP cache key includes at least the method and target URI. Stored Vary values can add request-field dimensions. More specialized mechanisms can alter selection. The recently standardized No-Vary-Search field, for example, can let a response declare query components that do not affect cache-key matching. That is a policy statement about equivalence among target URIs.

Cache-Status arrives on the other side of that choice. A hit can show that the reporting cache selected a stored response. A key can show its representation of the key. Neither proves that the origin was entitled to declare equivalence, that the cache implemented the rule correctly, or that two requests were semantically interchangeable for the application.

The organization must retain the rule that produced the key, the configuration version that implemented it, a safe fingerprint of the effective key and tests demonstrating tenant, language, authentication and personalization boundaries. Otherwise the header can document a perfectly executed unsafe decision.

A self-report can be authenticated, but only by design

RFC 9211 does not attach a signature or MAC to its members. A bare Cache-Status field is therefore not intrinsically tamper evident. HTTP Message Signatures can cover selected HTTP fields, but that mechanism requires an application profile: required components, acceptable algorithms, key discovery, signer authority, time handling and error behavior.

Simply adding a signature feature does not solve the evidence problem. The verifier must require Cache-Status among the covered components. It must know which actor signed at which point in a multi-intermediary path. Later caches may append members after an earlier signature. A valid signature proves a defined relationship between a signer and covered message components; it does not look inside the cache to prove that the claimed internal decision occurred.

For many operational systems, direct cryptographic coverage will be unnecessary. Controlled capture, authenticated debug access, trace correlation and independently retained internal telemetry can provide proportionate assurance. The important point is that assurance has an owner and a design. It does not appear automatically because the syntax is standardized.

Disclosure creates its own attack surface

The security section of RFC 9211 is unusually direct. Attackers can use Cache-Status to probe cache behavior and infer the activity of people using a shared cache. Knowing whether a response was stored can assist timing attacks on sensitive data. Exposing a key can reveal transformations that aid cache poisoning. Merely obfuscating a key does not remove the underlying risk.

The standard offers practical choices: omit the field, send it only to authorized clients, or restrict sensitive parameters to authorized clients. Those options move Cache-Status from a formatting decision into access governance.

An always-on minimal member may be safe for a public service. A detailed member containing key and local detail may belong behind authenticated diagnostic access. Some environments should emit nothing externally and export richer evidence to an internal observation system. The right answer depends on shared-cache sensitivity, tenant isolation, threat model and incident needs.

The policy must be enforced in running systems. A document that says “keys are internal” is symbolic if a debug header leaks them on a public route. Conversely, a security rule that removes every diagnostic field can leave incident teams dependent on the vendor that runs the cache. Least disclosure and independent accountability need to be designed together.

An investigation that respects the boundaries

Start with the raw response as observed. Preserve the complete ordered Cache-Status value, not a dashboard's HIT label. Record the observation point and time, method, target URI and relevant request fields. Preserve response status, Date, Age, Cache-Control, Expires, ETag, Last-Modified, Vary, Via and Proxy-Status.

Then bind each member to the expected path. Map its identifier to a cache tier, service version and configuration epoch. Check whether that tier was configured to emit the field for this audience. If key is needed, record a keyed fingerprint or an authorized redacted representation rather than copying a sensitive raw key into a broad incident channel.

Next, correlate the local claim. A hit should have an internal lookup event and cached-response identity. A forwarded stale response with fwd-status=304 should have a next-hop request and validator exchange. A collapsed request should have a collapse group and waiter count. A stored assertion should align with a storage event, even though later eviction remains possible.

Finally, test the application and user realities. Compare the delivered representation with the origin version intended for that request. Confirm authentication, tenant, language and personalization boundaries. Observe the customer's route after purge or policy repair. Closing an incident because the header changed from HIT to MISS merely replaces one cache fact with another.

Tests that make the field governable

A serious deployment needs invariant tests, not screenshots.

  • Produce a known hit and verify that the request does not reach the next hop.
  • Produce URI and Vary misses and require the most specific supported reasons.
  • Force revalidation and distinguish the next-hop 304 from the final client status.
  • Exercise approved stale serving and verify negative TTL without misclassifying the response as fresh.
  • Collapse concurrent misses and reconcile the field with origin request count and waiter fan-out.
  • Confirm that public responses omit sensitive key and detail parameters while authorized debug responses expose only the approved subset.
  • Verify member order and preservation across edge, shield, reverse proxy and gateway upgrades.
  • Inject an unknown extension or detail token and ensure tooling preserves it without inventing a meaning.
  • Where signatures are used, change an included field and require verification failure; then prove the profile actually covers Cache-Status.
  • Compare the field against internal telemetry and synthetic user checks, and alert on disagreement rather than selecting a preferred witness.

These tests convert a shared vocabulary into running evidence. Without them, an organization has standardized the shape of an assertion while leaving its production meaning to assumption.

The normative record and its limits

RFC 9211 defines the field and its parameters. The IANA Cache-Status registry coordinates extension names and types, while the HTTP Field Name Registry records Cache-Status as a permanent List field. RFC 9111 remains the authority for cache storage and reuse behavior.

Those documents create a common language. They do not prove adoption by a product, correctness in a fleet, completeness on a route or truth in a particular response. The narrow common specification succeeds when local operators preserve that distinction and build their own evidence around it.

Evidence record