Feature
Choose the Right Cloudflare Vary Action Without Breaking Responses
Compare Cloudflare Vary actions, see how normalization rewrites origin headers, and choose a restrictive cache policy with representation checks before rollout.
Impetuous · · 6 Min Read

Use normalize when your origin can return the correct representation from simplified header values. Use passthrough when distinctions removed by normalization affect the response. Use bypass when a header named in the origin’s Vary carries personalized, unpredictable or unbounded values. For public publishing endpoints, start with default bypass and explicitly configure the headers you have tested.
An English/French publication may be a good normalization candidate. A site that distinguishes US and UK English needs more care: normalization can change the request your origin receives, not just the cache key.
Choose the response scope and the header’s requirements; the tool recommends an action for that header.
Choose a Vary Action for One Header
normalize
Use an explicit normalize action for this reviewed header. For Accept and Accept-Language, test the rewritten origin request as well as cache matching.
Keep default bypass for unexpected Vary fields. This header affects cache matching only when the origin names it in Vary.
Without JavaScript, the displayed recommendation applies to the initial public-response and simplification selections only.
Source: Cloudflare Vary and Cache Rules settings. Recommendations assume cache eligibility is configured separately.
Cloudflare documents Vary in Cache Rules as available on Free, Pro, Business and Enterprise plans. It is separate from the existing Vary for images feature. The origin must name a header in Vary before that header’s configured action affects cache matching; configuring the header does not add it to every response’s cache key. (Cloudflare Vary documentation)
The Origin’s Vary Header Triggers the Action
An origin response might declare Vary: Accept, Accept-Language. The Cache Rule determines how Cloudflare handles each named request field.
| Action | Cache Behavior | Appropriate Use |
|---|---|---|
normalize |
Matches simplified values, with header-specific negotiation processing. | The origin works correctly with the simplified values. |
passthrough |
Matches raw values, retaining casing, whitespace, order and duplicates. Repeated lines are combined in order. | Removed distinctions matter and possible values are reasonably controlled. |
bypass |
Does not store a response when the configured header appears in Vary. |
Personalized, high-cardinality or unexpected variation. |
Vary: * always bypasses cache, regardless of the configured actions. These matching behaviors are described in Cloudflare’s launch explanation.
Neither passthrough nor a Vary bypass default is a privacy policy. Keep personalized responses outside shared caching: a Vary action depends on the origin naming the relevant header, and changing the action does not remove existing cache entries.
Passthrough also does not guarantee that Cloudflare leaves every request header untouched. Cloudflare can still override Accept-Encoding when Respect Strong ETags is disabled. (Compression and Vary behavior)
Normalize Can Rewrite the Origin Request
For Accept and Accept-Language, Cloudflare forwards normalized values to the origin on a miss or revalidation. This happens before Cloudflare sees the response, so the rewrite can occur even if that response ultimately omits Vary. If filtering leaves an empty value, Cloudflare removes the header from the origin request. (Origin request headers)
Consider two requests:
| Request | Original Accept-Language | Normalized Value |
|---|---|---|
| A | en-US, fr;q=0.8 |
en,fr |
| B | fr;q=0.8, en-GB |
en,fr |
With an allowlist of en, fr and de, both normalize to en,fr. That is useful if the origin serves one English edition. It is inappropriate if the origin needs the regional distinction to choose different content.
Cloudflare can retain an explicitly allowlisted regional tag, but that does not preserve every other detail of the original header. (Normalization examples)
Preference Weights and Client Ordering May Disappear
Cloudflare sorts by quality value, breaks ties alphabetically and removes nonzero quality parameters. An origin that needs numeric weights or the client’s ordering cannot assume those details survive normalization.
Test whether the application only needs the resulting preference order or actually uses the original weights. Those are different requirements: an origin can accept an ordered list while still producing a different result when numeric weights disappear.
Regional Tags and Exclusions Need Explicit Tests
Language tags can collapse to their base language, and entries outside the configured supported set can disappear.
The concept documentation says q=0 is preserved. The launch explanation nevertheless warns that shortening language tags or filtering can lose exclusions—for example, en-US;q=0 can become en. If exclusions must reach the origin intact, choose passthrough for that header rather than relying on preservation across those transformations. These limits are covered by the normalization reference and the launch explanation cited above.
Generic Headers Receive Narrower Normalization
For headers other than the negotiation headers, normalization combines repeated lines and trims optional whitespace. It does not lowercase, reorder or deduplicate values, and it does not understand a custom header’s application semantics.
Do not choose normalize for a custom header on the assumption that it will collapse equivalent application values. The simplification must match what Cloudflare actually does, not what your application considers equivalent.
Default Bypass Keeps Unexpected Variation Out of Cache
Cloudflare’s launch blog recommends normalize as the default. Its Cache Rules settings documentation instead recommends default bypass, with explicit expected headers. For a publisher’s production deployment, the restrictive approach is the better starting policy: unexpected origin variation stays out of cache rather than becoming an unaudited dimension. (Cache Rules settings)
For a public endpoint serving HTML or JSON in English, French and German, the proposed vary configuration is:
| Configuration Field | Action | Allowlist |
|---|---|---|
default |
bypass |
None |
headers.accept |
normalize |
text/html, application/json |
headers.accept-language |
normalize |
en, fr, de |
The corresponding action-parameter fragment is {"vary":{"default":{"action":"bypass"},"headers":{"accept":{"action":"normalize","media_types":["text/html","application/json"]},"accept-language":{"action":"normalize","languages":["en","fr","de"]}}}}.
This is the vary portion of a Cache Rule’s action parameters, not a complete API request. Scope the rule to the intended public endpoint and configure cache eligibility separately. The default object is required; allowlists support up to 10 media types and 20 languages, as documented in the settings reference above.
Two formats and three languages do not cap the cache at six keys. Preference order, missing headers and values that normalize to empty can create more variants, as the launch explanation describes.
If language details must remain intact, change accept-language to passthrough and remove its normalization allowlist. Keep the default restrictive; choosing passthrough for one reviewed header is not a reason to accept every unexpected Vary field.
Verify Representations Before Measuring Cache Hits
The rollout test must establish that requests share the right representation, not merely that they hit the cache.
Check Vary Across Responses Under the Same Base Key
Every cacheable representation under the same base key should declare the same appropriate Vary fields, including cacheable errors and fallbacks. An omitted field can allow the wrong response to be reused.
For an endpoint negotiating both language and format, inspect the HTML response, JSON response and cacheable fallback responses. Do not validate only the successful default-language page.
Test Equivalent and Distinct Requests
Repeat requests from the same client with reordered preferences, regional tags, q=0, missing headers and values outside the allowlist. Check the body, format and language—not just CF-Cache-Status.
Then look for hits after warming requests expected to share a variant. Requests that should produce different representations must remain distinct even if combining them would improve the hit rate.
Inspect origin-received headers as well. Confirm that the rewrite matches the application’s negotiation logic, especially when filtering produces an empty value or changes an exclusion.
Purge When the Policy Changes
Vary configuration changes do not automatically purge existing content. Purging a URL covers its Vary variants; existing custom-cache-key purge requirements still apply. Cloudflare’s rollout and purge guidance also covers origin consistency and representation testing.
Record the request cases and expected representations in a post-remediation verification checklist. A cache hit is useful only after the returned representation is correct.