Cache-Status
Diagnosing cache behavior across CDN layers requires a standardized reporting format. The Cache-Status response header reports cache handling details from each cache in the delivery chain, using the Structured Fields syntax.
Usage
The Cache-Status header is a standardized replacement for vendor-specific cache headers like X-Cache, X-Cache-Status, and X-Proxy-Cache. Instead of ad hoc values differing between CDN providers, Cache-Status uses a consistent format based on Structured Fields. Each cache in the request path appends its own entry to the header, creating a left-to-right record of how the response moved through the caching infrastructure.
Each entry starts with a cache identifier (the name of the forward proxy or CDN node) followed by parameters describing the cache interaction. The parameters indicate whether the response was a hit, why a forward request was made to the next hop, whether the response was stored, and how much TTL remains.
Platforms like Netlify already send this header in production. As adoption grows, Cache-Status provides a single header to inspect instead of checking vendor-specific alternatives.
Directives
hit
A boolean parameter. When present (hit), the cache
served the response from a stored entry. This is the
Structured Fields equivalent of X-Cache: HIT.
fwd
Indicates why the cache forwarded the request upstream
instead of serving from cache. Defined reasons include
miss (no matching entry), uri-miss (URI not in
cache), vary-miss (stored entry exists but Vary
fields did not match), request (request policy
forced forwarding), method (the request method
requires forwarding), stale (cached entry exceeded
its freshness lifetime), partial (a stored partial
response did not cover the requested ranges), and
bypass (cache was configured to skip caching for
this request).
fwd-status
An integer parameter containing the HTTP status code
received from the next-hop server. Appears only when
fwd is present and a forward request was made.
stored
A boolean parameter. When present (stored), the cache
saved the response for future use. A response served
as a miss and then stored will have both fwd=miss and
stored.
collapsed
A boolean parameter. When present (collapsed), the
cache combined this request with an existing in-flight
request to the same resource, avoiding duplicate backend
fetches.
ttl
An integer parameter representing the remaining freshness lifetime of the cached response in seconds at the time the response was sent. Helps operators gauge how long the cached copy will continue to be served before revalidation.
key
A string parameter containing the cache key used for this response. Useful for debugging when the cache key includes query parameters, cookies, or other varying components.
detail
A string parameter with a human-readable explanation. Caches use this for implementation-specific context not covered by the other parameters.
Example
A cache hit from Netlify Edge. The hit parameter
confirms the response was served directly from cache
without forwarding to the origin.
Cache-Status: "Netlify Edge"; hit
A cache miss at the edge. The fwd=miss parameter means
no matching cached entry existed, so the cache forwarded
the request to the origin server.
Cache-Status: "Netlify Edge"; fwd=miss
A stale cache entry triggered revalidation. The
fwd=stale parameter means the edge cache had a stored
copy, but the entry exceeded its freshness lifetime and
needed to be refreshed from the origin.
Cache-Status: "Netlify Edge"; fwd=stale
Multiple caches are listed left to right. Here, the
request passed through two cache layers. The durable
cache layer bypassed caching (fwd=bypass), and the edge
cache had no matching entry (fwd=miss). The detail
parameter provides additional implementation-specific
context.
Cache-Status: "Netlify Durable"; fwd=bypass,
"Netlify Edge"; fwd=miss;detail=p1
Who emits it, and reading a chain
Adoption in 2026 is narrow and real. Netlify Edge and Deno Deploy emit the header in production, while Cloudflare, Fastly, and Akamai continue with their vendor headers, Cf-Cache-Status and the X-Cache family among them. The standard exists to replace exactly this scatter, and so far the newer platforms adopted the replacement while the incumbents kept their formats.
List order carries meaning: the first member is the
cache closest to the origin and the last is closest
to the user, with each cache appending rather than
replacing, so a multi-CDN chain reads as a journey.
A negative ttl is valid and observed live,
reporting how many seconds ago the stored response
went stale. The fwd-status parameter separates what
the next hop returned from what the client received,
which is how a 304 revalidation surfaces inside
a chain ending in a 200.
Locally generated errors carry no member, so a missing entry from a proxy on an error response is correct behavior rather than a gap.
Emission is deliberately opt-in, and the specification names the risk plainly: the header teaches an attacker how the cache behaves, supports timing inference about other users, and exposes cache-key construction, which assists poisoning. Restricting the header to debugging traffic is the documented middle ground.
See also
- RFC 9211: The Cache-Status Structured Field
- X-Cache
- Cache-Control
- Caching
- Structured Fields
- HTTP headers