Cloudflare-CDN-Cache-Control
The HTTP Cloudflare-CDN-Cache-Control response header is an unofficial header directing the Cloudflare edge cache alone, leaving Cache-Control to govern browsers and any other proxy on the path.
Usage
Origins frequently want two different caching policies at once. An HTML page benefits from a long life at the edge, where a purge clears the copy on demand, and a short life in browsers, where no purge mechanism reaches. A single Cache-Control header forces one answer for both.
Cloudflare-CDN-Cache-Control resolves the conflict by addressing Cloudflare specifically. Directives inside the header apply at the edge, and the Cache-Control header travels to the browser untouched.
Cloudflare-CDN-Cache-Control: max-age=86400
Cache-Control: public, max-age=60
Cloudflare holds the response for a day and browsers revalidate after a minute. Publishing a change means purging the edge, after which the next visitor receives fresh content without waiting out a long browser lifetime.
The header accepts the same directives as
Cache-Control. Cloudflare documents
max-age and stale-if-error in its own examples,
and s-maxage adds nothing here, since a targeted
header already addresses a shared cache.
Precedence
Among the response headers themselves, Cloudflare resolves in a fixed order and the first present wins at the edge.
| Order | Header | Scope |
|---|---|---|
| 1 | Cloudflare-CDN-Cache-Control |
Cloudflare |
| 2 | CDN-Cache-Control | Any CDN |
| 3 | Cache-Control | Browsers and proxies |
Cache-Control sits last for Cloudflare specifically. Where either targeted header carries a valid, non-empty value, Cloudflare passes Cache-Control through without letting the value shape edge caching decisions. An empty or malformed targeted header is ignored entirely, and the fallback to Cache-Control happens silently, which makes a typo look like the header being disregarded.
Dashboard configuration outranks all three
Reading the header order alone leads to wrong conclusions, because several dashboard settings sit above every header the origin sends.
A Cache Response Rule setting cache-control takes precedence over both targeted headers. So does an Edge Cache TTL cache rule, which governs edge lifetime directly. Either explains an origin header with no apparent effect, and the dashboard is the first place to look before debugging the origin.
The ordering here reversed direction. Origin headers once had the final say over dashboard cache settings, and the arrival of Cache Response Rules inverted the relationship, so guidance written before 2026 describes the older behavior.
Surrogate-Control disrupts the chain
A Surrogate-Control header anywhere on the response makes Cloudflare disregard Cache-Control handling entirely, and the effect holds even when Surrogate-Control carries no directives at all. An origin emitting the header out of habit, or a framework adding the field by default, changes caching in ways the other three headers do not explain.
Downstream visibility
The two targeted headers behave differently on the way out, and the difference matters for anyone running a second CDN.
Cloudflare-CDN-Cache-Control stops at Cloudflare. The header controls one platform, so forwarding the value serves no purpose and Cloudflare removes the header before responding.
CDN-Cache-Control continues downstream, reaching any additional CDN between Cloudflare and the browser. A stack running Cloudflare in front of another proxy uses the vendor-specific header for Cloudflare and the generic one for whatever follows.
Cloudflare-CDN-Cache-Control: max-age=86400
CDN-Cache-Control: max-age=3600
Cache-Control: public, max-age=60
Cloudflare caches for a day, the downstream CDN for an hour, and the browser for a minute.
Common misconfigurations
Sending Cloudflare-CDN-Cache-Control alongside a
no-store in Cache-Control reads
as a contradiction and behaves exactly as written:
Cloudflare caches the response while browsers store
nothing. The pattern is deliberate on pages meant to
stay fresh per visitor and served fast from the edge,
and accidental when someone adds no-store for
privacy reasons without noticing the edge copy.
Setting the header carries a side effect worth
knowing. Cloudflare turns Origin Cache Control on
whenever Cloudflare-CDN-Cache-Control is present,
regardless of the account setting, and requests
carrying an Authorization header
then cache only under s-maxage, must-revalidate,
or public. Any other directive alongside
Authorization produces a BYPASS
rather than a stored object.
Debugging starts with Cf-Cache-Status
rather than the request headers, since the targeted
headers never reach a browser. Uncacheable responses
now report BYPASS across the board, where older
troubleshooting advice reads MISS as a failed
attempt to cache. A BYPASS on a response expected
to be stored points at a Cache Response Rule, a
no-store reaching the edge through the precedence
chain, or the Authorization
interaction above.
See also
- Cloudflare: CDN-Cache-Control
- RFC 9213: Targeted HTTP Cache Control
- CDN-Cache-Control
- Cache-Control
- Cache-Tag
- Cf-Cache-Status
- Caching
- HTTP headers