Dated report · 25 Oct 2026 · RFC 9213 and Cloudflare documentation
CDN-targeted Cache-Control
RFC 9213 defines a cache-specific policy-selection mechanism. Cloudflare documents its own precedence and forwarding for standard and proprietary targeted fields.
Finding
RFC 9213’s CDN-Cache-Control is a standardized, CDN-targeted response field. It lets a CDN use one policy while browsers and other caches use ordinary Cache-Control. By contrast, s-maxage is part of ordinary Cache-Control and applies to shared caches generally, not only CDNs. RFC 9213 §3; RFC 9111 §5.2.2.10.
A conforming targeted cache has an ordered list of field names. For each response, it selects the first valid, non-empty field on that list and uses its directives instead of the response’s ordinary Cache-Control and Expires. If no listed field is usable, it falls back to ordinary HTTP cache-control rules. The field name alone does not prove support or identify the cache’s target list. RFC 9213 §2.2.
The freshness model stays end-to-end. A CDN may use a longer targeted lifetime while a downstream browser or ordinary proxy sees the response’s accumulated Age exceed its shorter ordinary lifetime. “Fresh at the CDN” does not mean fresh at every downstream cache. RFC 9213 §2.3.
1. What targeted control adds beyond s-maxage
RFC 9111’s ordinary shared-cache freshness choice is s-maxage, then max-age, then Expires minus Date; a heuristic may apply where allowed if no explicit expiration is available. A private cache ignores s-maxage and normally uses max-age, then Expires, or an allowed heuristic. A response is fresh only when its freshness lifetime is greater than its current age. RFC 9111 §4.2, §5.2.2.1, §5.2.2.10, §5.3.
s-maxage overrides max-age and Expires for each shared cache using ordinary rules. It also imports proxy-revalidate semantics, requiring successful validation before stale reuse, and it can permit shared reuse of a response to a request carrying Authorization under RFC 9111 §3.5. It does not distinguish a CDN from a shared proxy. RFC 9111 §3.5; §5.2.2.10.
RFC 9213 adds a separate targeting mechanism. Its targeted field carries cache directives with a distinct field name for a particular class of cache. RFC 9213 defines CDN-Cache-Control for caches in a distributed network operating on behalf of an origin (a CDN). A targeted cache must implement at least max-age, must-revalidate, no-store, no-cache, and private; it should implement other directives that it supports in ordinary Cache-Control. In either policy, no-store and no-cache make max-age inoperative. RFC 9213 §2.2.
2. Target-list selection and fallback
- The cache has an ordered target list. The most applicable field name comes first. The list may be fixed, configured, or generated per request.
- The cache selects the first field on that list whose value is valid, non-empty, and parsable. It applies that field’s directives instead of the response’s ordinary
Cache-ControlandExpires; this is not directive-by-directive merging. - An empty field or a field with a parsing error is ignored. If no listed field is usable, the cache falls back to ordinary HTTP cache-control mechanisms, including the shared-cache
s-maxage/max-age/Expiresorder. - A targeted field not on the cache’s list must not change that cache’s behavior and must be passed through. The
-Cache-Controlsuffix is a field-name convention; it is not proof that the cache recognizes the field.
Targeted values are Structured Field Dictionaries, not ordinary Cache-Control fields with alternate names. RFC 9213 warns that parsing a targeted field with a Cache-Control parser can create interoperability problems. For example, max-age takes an integer; a decimal such as max-age=2.5 is not a valid integer value. RFC 9213 §2.1; RFC 8941.
Each cache applies its own ordered target list to each response; no usable targeted match returns the cache to ordinary HTTP controls.
- Target list — ordered field names for this cache
- Selection — first listed field that is valid and non-empty
- Selected policy — targeted directives replace ordinary Cache-Control and Expires for that cache
- No usable match — apply ordinary HTTP cache-control selection
3. One freshness model and Age
RFC 9111 defines Age as an estimate, in seconds, of time since the response was generated or successfully validated at the origin. It reflects residence in caches along the path plus transit time; it is not a new freshness clock that starts at each hop. A cache compares its selected freshness lifetime with the message’s current age. RFC 9111 §4.2.1, §4.2.3, §5.1.
A cache using CDN-Cache-Control: max-age=600 can consider a response fresh at Age: 300. A downstream browser using Cache-Control: max-age=60 and an ordinary shared proxy using s-maxage=120 can each consider that same response stale. Those caches may need to validate or fetch rather than reuse it without validation. RFC 9213 §2.3 uses Age: 1800, max-age=600, and CDN-Cache-Control: max-age=3600 to make the same distinction.
RFC 9213 mentions possible deployment techniques such as removing Age or updating Date/Expires, but does not require them. Do not assume a provider resets age or rewrites dates unless that named product documents it or an authorized capture establishes it. A targeted lifetime does not erase accumulated age.
4. Synthetic response matrix
Assumptions: public, identical static content; a GET response; no personalized data or request-side directives; no local override; and Age: 300 at the downstream response. The response is invented to illustrate policy selection. It was not sent to any cache.
HTTP/1.1 200 OK
Date: Sun, 25 Oct 2026 06:00:00 GMT
Age: 300
Cache-Control: public, max-age=60, s-maxage=120
CDN-Cache-Control: public, max-age=600
Cloudflare-CDN-Cache-Control: public, max-age=900
| Cache considered | Assumed policy | Freshness input | At Age 300 | Does not establish |
|---|---|---|---|---|
| Browser/private cache | Does not target CDN fields; private caches ignore s-maxage. | max-age=60 | Stale; validate before reuse where required. | Universal browser support for RFC 9213 or a browser reload result. |
| Ordinary shared proxy | No targeted field on its list; uses ordinary HTTP controls. | s-maxage=120 | Stale; s-maxage overrides ordinary max-age and Expires. | That every shared proxy is ordinary rather than CDN-aware. |
| Another RFC 9213 CDN | Target list is [CDN-Cache-Control]; the Cloudflare-specific name is unlisted and passed through. | CDN-Cache-Control: max-age=600 | Fresh under this policy. | That a particular provider implements RFC 9213 or forwards the field. |
| Cloudflare, per current docs | Uses Cloudflare-CDN-Cache-Control ahead of CDN-Cache-Control; no higher-precedence rule is assumed. | Cloudflare-CDN-Cache-Control: max-age=900 | Fresh under the documented header policy. | That a live zone uses these headers, the documented rule, or this Age. |
If the CDN has no usable targeted field on its list, the ordinary fallback applies. In this example ordinary max-age and s-maxage are present, so Expires would not set the selected lifetime. Without explicit freshness, an allowed heuristic may be relevant under RFC 9111. [RFC 9213][RFC 9111]
Header-example check: under the stated target lists and no-override assumptions, the matrix is correct as an RFC/vendor-documentation example. It demonstrates distinct expected freshness policies and downstream staleness. It does not show storage, a cache hit, actual Age, browser behavior, provider support, configuration, or a live deployment.
5. Cloudflare-specific precedence and forwarding
The following behavior comes from Cloudflare product documentation. It is not a requirement for all RFC 9213 implementations. Cloudflare documents its proprietary field as more specific than the standardized CDN field.
| Origin fields | Documented Cloudflare cache input | Documented downstream behavior |
|---|---|---|
CDN-Cache-Control (and possibly Cache-Control) | Cloudflare evaluates CDN-Cache-Control; ordinary Cache-Control does not affect the Cloudflare decision when the targeted field is used. | Cloudflare proxies the standard field downstream for other CDNs and proxies ordinary Cache-Control as received. |
Cloudflare-CDN-Cache-Control (and possibly ordinary Cache-Control) | Cloudflare uses its proprietary field as its Cloudflare-specific policy. | Cloudflare does not proxy the proprietary field; downstream caches use ordinary Cache-Control/Expires if present, or their normal fallback. |
| Both targeted fields | Cloudflare-CDN-Cache-Control takes precedence over CDN-Cache-Control. | The standard field is forwarded for downstream CDNs; the proprietary field is suppressed. |
The specific-field-first behavior is consistent with an RFC 9213-style target list such as [Cloudflare-CDN-Cache-Control, CDN-Cache-Control], but the exact Cloudflare implementation remains a product rule. RFC 9213 says a cache using CDN-Cache-Control typically forwards it and may remove it when undesirable. Cloudflare documents forwarding the standard field and suppressing the proprietary field. RFC 9213 §3.1; Cloudflare CDN-Cache-Control.
Rules that can change the result
- A Cache Response Rule using
set_cache_controltakes precedence over origin-setCloudflare-CDN-Cache-ControlandCDN-Cache-Control. Cloudflare says Cache Response Rules take precedence over conflicting Cache Rules. Its example has a response rule’ss-maxage=3600win over a Cache Rule Edge TTL of 7200 seconds. - A Cache Rule’s Edge Cache TTL overrides the targeted header’s edge lifetime. Browser Cache TTL changes only the ordinary
Cache-Controlresponse field; it does not modify either targeted field. Cloudflare saysExpiresdoes not affect its caching decision when targeted fields are used. If no targeted or ordinary cache-control value is received, Cloudflare directs cacheable assets to its general defaults. - Cloudflare’s CDN-Cache-Control page says surrogates do not honor origin
Cache-ControlwhenSurrogate-Controlis present, even when that field has no directives. The documentation does not establish a complete ordering ofSurrogate-Controlagainst both targeted fields; that combination remains a configuration question. - Cloudflare’s cache-response documentation gives header precedence as
Cloudflare-CDN-Cache-Control>CDN-Cache-Control>Cache-Control. It documents targetedno-storeor bareprivateas possible BYPASS cases. An Edge Cache TTL rule configured to ignore origin controls overrides those directives. Cloudflare describesno-cache,max-age=0, ors-maxage=0as cache-and-revalidate paths under applicable Origin Cache Control behavior rather than BYPASS. These are Cloudflare behavior statements and remain configuration-dependent. - Cloudflare’s Origin Cache Control page adds an Authorization caveat: setting
Cloudflare-CDN-Cache-Controlturns OCC on regardless of the ordinary OCC toggle. Cloudflare then applies its Authorization logic and documentss-maxage,must-revalidate, orpublicas permitting cache in that case. Do not treat that product-specific table as a universal rule or as evidence that any response is safe to share.
This targeted-field guide complements the separate Cloudflare Cache Rules and Origin Cache Control guide, which focuses on edge/browser TTL, keys, and purge scope.
6. Privacy eligibility and cache-key boundary
RFC 9213 warns that multiple policies can confuse deployments and cause unintended reuse of sensitive information. A valid targeted field can intentionally tell the target cache to store a response even while ordinary Cache-Control: no-store prevents other caches from storing it. Therefore a generic private or no-store field is not necessarily a veto for a targeted cache that selected a separate valid policy. RFC 9213 §5; §3.1.
private prevents shared storage when it is the selected policy; no-store applies to private and shared caches; and no-cache permits storage but requires successful validation before reuse. RFC 9111 cautions that no-store alone is not a reliable privacy guarantee against malicious or compromised caches. If a CDN must not store a response, include the restrictive directive in the targeted field that it actually selects or omit that targeted field. Do not assume the selected field is merged with ordinary controls. RFC 9111 §5.2.2.4, §5.2.2.5, §5.2.2.8.
Freshness policy is not identity policy. RFC 9111’s minimum cache key includes request method and target URI. Vary can distinguish representations using nominated request fields, and implementations may add other key material. A targeted field does not add Cookie, Authorization, tenant, language, device, query, or any other dimensions to a key. A key that collapses user-, tenant-, or content-negotiation variants can expose or mis-serve data even with a correct TTL. RFC 9111 §2; §4.1.
Cloudflare custom cache-key settings are separate from targeted-field selection and have their own product and plan constraints. This review did not re-audit all selector counts or request-size limits from the earlier Cloudflare guide. Check the exact current account settings and resulting key for an authorized named zone; no key option or Vary policy is assumed here.
7. Limits and unresolved questions
- No universal support claim. RFC 9213 defines semantics for conforming caches; it does not prove that a specific CDN, browser, proxy, or downstream network implements or enables targeted fields. A target list can vary by request.
- No zone result. Cloudflare’s docs do not reveal an unprovided zone’s Cache Response Rules, Cache Rules, OCC state, Edge/Browser TTL, key, headers, POP/tier behavior, or response age.
- Unverified details. Malformed or empty targeted-field handling at a particular Cloudflare configuration, age/date rewriting, additional products, and a concrete downstream topology were not tested. Apply RFC 9213 requirements to conforming implementations, not as a deployment observation.
- No live probe. No authorized URL or target was supplied, so no browser capture, HTTP request, cache hit,
Age, or downstream-staleness observation was attempted. No third-party system test was authorized or run. - Example scope. The synthetic matrix illustrates standards and vendor documentation only. It is not a universal configuration recommendation. Review privacy and key isolation before increasing a CDN lifetime for private or credentialed content.
Primary source ledger
RFC Editor HTML for RFC 9213, RFC 9111, and RFC 8941 and the following Cloudflare documentation were checked 25 Oct 2026, 06:09–06:12 UTC. RFC 9213 and RFC 9111 are IETF Standards Track documents published June 2022.
Standards
- RFC 9213 — Targeted HTTP Cache Control: §§2.1 (Structured Fields parsing), 2.2 (target lists, selection, fallback, pass-through, and directives), 2.3 (end-to-end freshness and the Age example), 2.4 (field registration/convention), 3–3.1 (CDN target and forwarding), and 5 (security considerations).
- RFC 9111 — HTTP Caching: §2 (cache key), §3 (storage eligibility), §3.5 (Authorization), §4.1 (
Vary), §§4.2–4.2.3 (freshness and age), §§5.1–5.3 (Age,Cache-Control, andExpires), and §§5.2.2.1, 5.2.2.4–5.2.2.10 (cache directives). - RFC 8941 — Structured Field Values for HTTP: dictionary syntax referenced by RFC 9213 §2.1.
Cloudflare documentation
- CDN-Cache-Control (last updated 16 Apr 2026): precedence, forwarding/suppression, Edge/Browser Cache TTL interactions,
Expires, and examples. - Cache responses: documented response-header precedence, BYPASS and revalidation explanations, and Edge TTL exception.
- Origin Cache Control: OCC directives, Authorization condition, and proprietary-field interaction.
- Cache Response Rules: precedence over origin-set targeted headers and Cache Rules, including the
set_cache_controlexample.