Skip to content

[Cache] Document CDN-Cache-Control as a BYPASS cause - #32569

Open
ngayerie wants to merge 5 commits into
productionfrom
ngayerie/cache-cdn-cache-control-bypass
Open

[Cache] Document CDN-Cache-Control as a BYPASS cause#32569
ngayerie wants to merge 5 commits into
productionfrom
ngayerie/cache-cdn-cache-control-bypass

Conversation

@ngayerie

@ngayerie ngayerie commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Two small follow-ups to #32423.

What

  • Add a bullet to the BYPASS lists in cache-responses.mdx and investigating-uncached-responses.mdx documenting Cloudflare-CDN-Cache-Control and CDN-Cache-Control, with the precedence chain Cloudflare-CDN-Cache-Control > CDN-Cache-Control > Cache-Control. Uses a concrete example so the reader sees that a cacheable Cache-Control alongside a non-cacheable CDN-Cache-Control still produces BYPASS.
  • Rewrite the Age callout in cache-responses.mdx and the corresponding HIT-verification bullet in the troubleshooting page. Both currently mention CacheTieredFill=true, which is an http_requests Logpush field, not an HTTP header — readers cannot observe it on a response.

Why

Neither BYPASS list mentioned Cloudflare-CDN-Cache-Control or CDN-Cache-Control. When both Cache-Control and CDN-Cache-Control are set, CDN-Cache-Control wins per CDN-Cache-Control, so a reader debugging a BYPASS while only looking at Cache-Control has no signal from these pages that another header is in play.

@zaidoon1 for review.

@ngayerie
ngayerie requested review from a team, ack-cf and zaidoon1 as code owners August 6, 2026 09:29
@cloudflare-docs-bot

cloudflare-docs-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review

⚠️ 3 warnings found in commit f1675c0.

👉 Fix in your agent 👈
Fix the following review findings in PR #32569 (https://github.com/cloudflare/cloudflare-docs/pull/32569).

Before making changes, review each finding and present a brief summary table:
- For each finding, state whether you agree, disagree, or need clarification
- If you disagree (e.g. the fix requires disproportionate effort for minimal benefit,
  or the finding is factually incorrect), explain why
- If you need clarification before deciding, ask those questions
- Then share your plan for which issues to tackle and in what order

After triaging, follow this order:
1. Post a comment on this PR for any findings you are skipping, with the finding ID and your reasoning.
2. Then commit the fixes for the legitimate findings.

The comment must come before the commit — the bot reads PR comments when a new
push triggers a review, so skip comments posted after the push will be missed.

---

## Code Review

### Warnings (2)

#### CR-6e16d4b86f8b · Inconsistent CDN-Cache-Control BYPASS guidance
- **File:** `src/content/docs/cache/troubleshooting/investigating-uncached-responses.mdx` line 44
- **Issue:** Line 44 claims `no-cache` and `max-age=0` in `Cloudflare-CDN-Cache-Control` or `CDN-Cache-Control` do not produce `BYPASS`. However, `src/content/docs/cache/concepts/cache-control.mdx` states that when `Cloudflare-Cdn-Cache-Control` is set, only `s-maxage`, `must-revalidate`, or `public` directives allow caching and 'if any other directive is present, we do not cache the asset and instead return `BYPASS`.' This contradicts the claim that `no-cache`/`max-age=0` in these headers do not produce `BYPASS`.
- **Fix:** Confirm the correct behavior and update either this page or the Origin Cache Control concept page so the two documents give consistent guidance.

#### CR-16749eabeb7e · Contradicts existing Authorization behavior
- **File:** `src/content/docs/cache/concepts/cache-responses.mdx` line 58
- **Issue:** The new bullet states that `no-cache`, `max-age=0`, or `s-maxage=0` in `Cloudflare-CDN-Cache-Control` or `CDN-Cache-Control` "do not produce `BYPASS`" and instead produce `MISS` then `REVALIDATED`/`EXPIRED`. However, `/cache/concepts/cache-control/#conditions` states that when `Cloudflare-Cdn-Cache-Control` is set, OCC is forced on and the Authorization logic permits caching only if the header contains `s-maxage`, `must-revalidate`, or `public`; any other directive returns `BYPASS`. Because `no-cache` and `max-age=0` are not in that list, a request with an `Authorization` header and a `Cloudflare-CDN-Cache-Control: no-cache` (or `max-age=0`) response would be `BYPASS`, not cache-and-revalidate. The blanket statement conflicts with the existing Authorization caveat documented on the same page for `Cache-Control`.
- **Fix:** Add the same `Authorization` caveat used for `Cache-Control` — or explicitly scope the "does not produce BYPASS" claim to the non-Authorization case — and reconcile the wording with the existing note in `/cache/concepts/cache-control/`.

---

## Style Guide Review

### Warnings (1)

#### SG-a13f75382190 · HTTP headers must use monospace
- **File:** `src/content/docs/cache/troubleshooting/investigating-uncached-responses.mdx` line 43
- **Issue:** Line contains `ignores origin cache-control` where the Cache-Control header reference is not in backticks.
- **Fix:** Change `origin cache-control` to `origin Cache-Control` or `origin \`Cache-Control\``.

Code Review

This code review is in beta and may not always be helpful — use your judgment.

Warnings (2)
File Issue
cache/troubleshooting/investigating-uncached-responses.mdx line 44 Inconsistent CDN-Cache-Control BYPASS guidance — Line 44 claims no-cache and max-age=0 in Cloudflare-CDN-Cache-Control or CDN-Cache-Control do not produce BYPASS. However, src/content/docs/cache/concepts/cache-control.mdx states that when Cloudflare-Cdn-Cache-Control is set, only s-maxage, must-revalidate, or public directives allow caching and 'if any other directive is present, we do not cache the asset and instead return BYPASS.' This contradicts the claim that no-cache/max-age=0 in these headers do not produce BYPASS. Fix: Confirm the correct behavior and update either this page or the Origin Cache Control concept page so the two documents give consistent guidance.
cache/concepts/cache-responses.mdx line 58 Contradicts existing Authorization behavior — The new bullet states that no-cache, max-age=0, or s-maxage=0 in Cloudflare-CDN-Cache-Control or CDN-Cache-Control "do not produce BYPASS" and instead produce MISS then REVALIDATED/EXPIRED. However, /cache/concepts/cache-control/#conditions states that when Cloudflare-Cdn-Cache-Control is set, OCC is forced on and the Authorization logic permits caching only if the header contains s-maxage, must-revalidate, or public; any other directive returns BYPASS. Because no-cache and max-age=0 are not in that list, a request with an Authorization header and a Cloudflare-CDN-Cache-Control: no-cache (or max-age=0) response would be BYPASS, not cache-and-revalidate. The blanket statement conflicts with the existing Authorization caveat documented on the same page for Cache-Control. Fix: Add the same Authorization caveat used for Cache-Control — or explicitly scope the "does not produce BYPASS" claim to the non-Authorization case — and reconcile the wording with the existing note in /cache/concepts/cache-control/.

Conventions

No convention issues found.

Style Guide Review

Warnings (1)
File Issue
cache/troubleshooting/investigating-uncached-responses.mdx line 43 HTTP headers must use monospace — Line contains ignores origin cache-control where the Cache-Control header reference is not in backticks. Fix: Change origin cache-control to origin Cache-Control or origin \Cache-Control``.
Commands

Only codeowners can run commands. Post a comment with the command to trigger it.

Command Description
/review Runs a review now. Incremental if a prior review exists, full if not.
/full-review Re-reviews the entire PR diff from scratch, ignoring incremental history. Useful after a rebase, when you want a fresh review, or if the bot gets out of sync and reports issues that no longer exist.
/ignore-review-limit Permanently lifts the 2-review automatic limit for this PR. Future pushes will trigger reviews as normal.
/disable-auto-review Stops automatic reviews from triggering on future pushes to this PR. Codeowners can still run /review or /full-review manually.
/rebase Rebases the PR branch against production. On conflict, attempts to resolve automatically using AI. Stops with an explanation if confidence is not high enough.

@github-actions github-actions Bot added product:cache Issues or PRs related to Cache size/xs labels Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

This pull request requires reviews from CODEOWNERS as it changes files that match the following patterns:

Pattern Owners
/src/content/docs/cache/ @cloudflare/product-owners, @ack-cf, @zaidoon1, @mbullock1986

Comment thread src/content/docs/cache/concepts/cache-responses.mdx Outdated
Comment thread src/content/docs/cache/concepts/cache-responses.mdx Outdated
Common reasons the origin response is treated as not cacheable include:

* The response exceeds the [maximum cacheable file size](/cache/concepts/default-cache-behavior/#cacheable-size-limits) for your plan.
* The origin returned a `Cloudflare-CDN-Cache-Control` or `CDN-Cache-Control` header with a non-cacheable directive. Cloudflare evaluates these headers ahead of `Cache-Control`, in the precedence `Cloudflare-CDN-Cache-Control` > `CDN-Cache-Control` > `Cache-Control`. For example, an origin returning both `Cache-Control: public, max-age=3600` and `CDN-Cache-Control: no-store` produces `BYPASS`. Inspect every response header, not just `Cache-Control`. Refer to [CDN-Cache-Control](/cache/concepts/cdn-cache-control/) for the precedence rules.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good call, maybe we want to mention Surrogate-Control too.

Cloudflare-CDN-CC > CDN-CC > Surrogate-Control > Cache-Control

cc @zaidoon1

@foreseaz

foreseaz commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Both changes LGTM. Left some nits to make the existing change more clear, thanks for the effort @ngayerie

@ngayerie
ngayerie force-pushed the ngayerie/cache-cdn-cache-control-bypass branch from 7ebf475 to 2f583e2 Compare August 17, 2026 15:34
@ngayerie
ngayerie requested a review from mbullock1986 as a code owner August 17, 2026 15:34
@ngayerie

Copy link
Copy Markdown
Collaborator Author

Hi @mbullock1986 @zaidoon1
Would it be possible for you to review/approve this PR?
Thanks!

- Add a BYPASS bullet documenting Cloudflare-CDN-Cache-Control and
  CDN-Cache-Control, and their precedence over Cache-Control. An
  origin returning cacheable Cache-Control alongside a non-cacheable
  CDN-Cache-Control directive produces BYPASS, and readers otherwise
  have no signal that these two headers even exist as BYPASS causes.
- Rewrite the Age callout and HIT confirmation to describe the
  Tiered Cache lower-tier fill in plain language, without referring
  to the internal CacheTieredFill=true field. That field is only
  visible in the http_requests Logpush dataset, not in HTTP
  responses, so it is not something readers can inspect.
Address SG-619a15c3d17a from the docs bot review.
Clarify that Age is per-data-center scope: the seconds since the
serving data center's local cache admitted or last revalidated the
object, rather than the vaguer 'time in Cloudflare's cache'.

Applies @foreseaz's suggestion.
@ngayerie
ngayerie force-pushed the ngayerie/cache-cdn-cache-control-bypass branch from 2f583e2 to ee9f456 Compare August 17, 2026 19:12

@zaidoon1 zaidoon1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked the CDN-Cache-Control and Age claims against actual behavior. The BYPASS bullet's core point is right, but a few details need tightening. Comments inline.

Comment thread src/content/docs/cache/concepts/cache-responses.mdx Outdated
Common reasons the origin response is treated as not cacheable include:

* The response exceeds the [maximum cacheable file size](/cache/concepts/default-cache-behavior/#cacheable-size-limits) for your plan.
* The origin returned a `Cloudflare-CDN-Cache-Control` or `CDN-Cache-Control` header with a non-cacheable directive. Cloudflare evaluates these headers ahead of `Cache-Control`, in the precedence `Cloudflare-CDN-Cache-Control` > `CDN-Cache-Control` > `Cache-Control`. For example, an origin returning both `Cache-Control: public, max-age=3600` and `CDN-Cache-Control: no-store` produces `BYPASS`. Inspect every response header, not just `Cache-Control`. Refer to [CDN-Cache-Control](/cache/concepts/cdn-cache-control/) for the precedence rules.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example reads as unconditional. An Edge TTL that ignores origin cache-control overrides CDN-Cache-Control: no-store the same way it overrides Cache-Control: no-store, so with that rule in place these two headers give MISS then HIT. The no-store bullet right below already carries that exception, and the CDN-Cache-Control page says Edge Cache TTL wins.

Comment thread src/content/docs/cache/concepts/cache-responses.mdx Outdated
The `Age` response header is returned when Cloudflare serves a response from a local cache object on the data center handling the request. It is the number of seconds since that object was admitted or last revalidated at that cache. It resets if the asset is revalidated, purged, or evicted and then re-cached.

The `Age` header is only present for responses served from the cache. It will not appear on a cache MISS, dynamic traffic, the first request that populates the lower tier HIT from tiered cache `CacheTieredFill=true` or any responses that did not originate from the cache (for example, responses generated by a Worker that bypassed the cache).
The `Age` header is only present for responses served from the cache. It will not appear on a cache MISS, dynamic traffic, the first request that populates a lower-tier data center's cache from an upper tier via [Tiered Cache](/cache/how-to/tiered-cache/), or any responses that did not originate from the cache (for example, responses generated by a Worker that bypassed the cache).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too strong in both directions.

Age is absent on EXPIRED and REVALIDATED when the request actually revalidated against the origin, and those still count as served from cache. It's present on HIT, STALE, and UPDATING.

Other direction: an Age set by the origin still reaches the client on uncacheable responses. Origin sends Age: 42, status comes back DYNAMIC or BYPASS, client sees Age: 42. So "will not appear on a cache MISS" only holds when the origin didn't send one.

The request was eligible for cache, but the origin response or configuration prevented Cloudflare from storing it. Common causes:

- **The response exceeds the [cacheable size limit](/cache/concepts/default-cache-behavior/#cacheable-size-limits) for your plan.** Split the object into smaller assets, or move to a plan with a higher limit. [R2](/r2/) is an origin storage alternative — it does not raise the CDN cacheable size limit.
- **The origin returned a `Cloudflare-CDN-Cache-Control` or `CDN-Cache-Control` header with a non-cacheable directive.** Cloudflare evaluates these headers ahead of `Cache-Control`, in the precedence `Cloudflare-CDN-Cache-Control` > `CDN-Cache-Control` > `Cache-Control`. For example, an origin returning both `Cache-Control: public, max-age=3600` and `CDN-Cache-Control: no-store` produces `BYPASS`. Inspect every response header, not just `Cache-Control`. Refer to [CDN-Cache-Control](/cache/concepts/cdn-cache-control/) for the precedence rules.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Inspect every response header" won't surface Cloudflare-CDN-Cache-Control. Cloudflare doesn't return that one to the client, so it's invisible from the response side. That's the useful bit for a troubleshooting page: if you see BYPASS with no CDN-Cache-Control in the response, check what the origin actually sent, or have the origin drop the header and retest.

Same two points I left on the cache-responses.mdx bullet apply here.

cache-responses.mdx:
- Age callout scope: drop 'at that cache' — Age tracks the object's age
  in Cloudflare's network-wide cache, not a single data center. A HIT
  served locally can carry an Age inherited from an upper tier under
  Tiered Cache.
- Age status enumeration: rewrite by cf-cache-status. Age is set on
  HIT, STALE, UPDATING. It is absent on MISS, on EXPIRED and REVALIDATED
  when the request revalidated against the origin, and on DYNAMIC,
  BYPASS, NONE/UNKNOWN. Origin-set Age on uncacheable responses is
  proxied to the client — a DYNAMIC or BYPASS response can carry an
  Age value that came from the origin, not from Cloudflare.
- CDN-Cache-Control BYPASS bullet:
    - Name the directives: only no-store and bare private produce
      BYPASS. no-cache, max-age=0, s-maxage=0 do not — they produce
      MISS then REVALIDATED or EXPIRED.
    - Add the Edge Cache TTL override, same as for Cache-Control:
      no-store.
    - Drop the Origin Cache Control condition — these headers always
      follow OCC-style semantics regardless of the zone setting.

investigating-uncached-responses.mdx:
- Mirror the same CDN-Cache-Control corrections, framed for the
  troubleshooting reader: note that Cloudflare does not forward
  Cloudflare-CDN-Cache-Control to the client, so a BYPASS without a
  visible CDN-Cache-Control header means checking what the origin
  actually sent (or dropping the header at origin and retesting).
- HIT verification Age bullet: reconcile with the Age scope correction.
  With Tiered Cache, a fresh local fill can already report a large Age
  inherited from an upper tier — not 'may be absent'.

Copy link
Copy Markdown
Collaborator Author

[AI] Thanks @zaidoon1 — all 5 comments applied in 26b189cb.

cache-responses.mdx

  1. Age callout scope — dropped at that cache, kept it network-wide, and added the Tiered Cache clarification (HIT served locally can carry an Age inherited from an upper tier, so the value can be older than the last local fill).
  2. Age status enumeration — rewritten by cf-cache-status: Age is set on HIT, STALE, UPDATING. It is absent on MISS, on EXPIRED and REVALIDATED when the request revalidated against the origin, and on DYNAMIC, BYPASS, NONE/UNKNOWN. Origin-set Age on an uncacheable response is proxied to the client unchanged.
  3. CDN-Cache-Control BYPASS bullet — named the directives (only no-store and bare private produce BYPASS; no-cache/max-age=0/s-maxage=0 produce MISS then REVALIDATED/EXPIRED), dropped the Origin Cache Control condition (these headers follow OCC-style semantics regardless of the zone setting).
  4. CDN-Cache-Control BYPASS bullet — added the Edge Cache TTL override, same as Cache-Control: no-store.

investigating-uncached-responses.mdx

  1. CDN-Cache-Control BYPASS bullet — mirrored the same corrections, and reframed the troubleshooting angle: noted that Cloudflare does not forward Cloudflare-CDN-Cache-Control to the client, so if a reader sees BYPASS without a visible CDN-Cache-Control header the next step is checking what the origin actually sent (or dropping the header at origin and retesting), not "inspect every response header".

Also reconciled the HIT verification bullet on the same page with your Age scope correction — a fresh local fill from an upper tier can already report a large Age, so "may be absent" was wrong.

@zaidoon1 zaidoon1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latest addresses everything I raised. One clause got lost in the rewrite that I'd put back, plus a couple of small things.

Comment thread src/content/docs/cache/troubleshooting/investigating-uncached-responses.mdx Outdated
Comment thread src/content/docs/cache/concepts/cache-responses.mdx Outdated
Comment thread src/content/docs/cache/concepts/cache-responses.mdx Outdated
Comment thread src/content/docs/cache/troubleshooting/investigating-uncached-responses.mdx Outdated
cache-responses.mdx:
- Age callout: qualify the reset rule as 'revalidation against the
  origin'. With Tiered Cache, a lower tier revalidating against an
  upper tier that still has the object picks up the upper tier's age
  rather than resetting to zero.
- CDN-Cache-Control BYPASS bullet: split the sentence on the
  no-cache/max-age=0/s-maxage=0 clarification per style guide (no
  semicolons).

investigating-uncached-responses.mdx:
- CDN-Cache-Control BYPASS bullet: pull the no-cache/max-age=0/
  s-maxage=0 clarification into its own bullet. Six-sentence walls
  are hard to scan while debugging, and the clarification points the
  reader elsewhere (to Repeated MISS), so it earns a separate bullet.
  Also removes the semicolon flagged on the reference page.
- HIT verify Age bullet: restore the absent-on-fill case. On the
  request that fills a lower tier from an upper tier, the client gets
  HIT with no Age at all — the HIT reflects the upper tier, and the
  local data center has not served it from cache yet. The next
  request includes Age and can already be large under Tiered Cache.

Copy link
Copy Markdown
Collaborator Author

[AI] Thanks @zaidoon1 — all 4 comments applied in f1675c05.

  1. Age reset rule — qualified as revalidation against the origin, matching the phrasing on the paragraph below. A lower tier revalidating against an upper tier that still has the object picks up the upper tier's age, so the unqualified revalidation was wrong for Tiered Cache.
  2. Semicolon on cache-responses.mdx line 58 — split into two sentences.
  3. Six-sentence bullet on the troubleshooting page — pulled the no-cache/max-age=0/s-maxage=0 clarification into its own bullet. It's the clause that tells the reader to look under Repeated MISS instead, so it earns the separate bullet. That split also removed the matching semicolon on the troubleshooting page.
  4. HIT verify Age bullet — restored the absent-on-fill case: on the request that fills a lower-tier data center from an upper tier, the client gets HIT with no Age at all, because the local data center has not served it from cache yet. Subsequent requests include Age, and with Tiered Cache the value can already be large — kept the "increases on subsequent requests" signal you called out.

@zaidoon1 zaidoon1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small ones on the new bullet, neither blocking.


- **The response exceeds the [cacheable size limit](/cache/concepts/default-cache-behavior/#cacheable-size-limits) for your plan.** Split the object into smaller assets, or move to a plan with a higher limit. [R2](/r2/) is an origin storage alternative — it does not raise the CDN cacheable size limit.
- **The origin returned `no-store` or bare `private` in a `Cloudflare-CDN-Cache-Control` or `CDN-Cache-Control` header.** Cloudflare evaluates these headers ahead of `Cache-Control`, in the precedence `Cloudflare-CDN-Cache-Control` > `CDN-Cache-Control` > `Cache-Control`. An origin returning `Cache-Control: public, max-age=3600` together with `CDN-Cache-Control: no-store` produces `BYPASS`. Cloudflare does not forward `Cloudflare-CDN-Cache-Control` to the client, so it is not visible in the response — if you see `BYPASS` without a `CDN-Cache-Control` header, check what the origin actually sent, or have the origin drop the header and retest. A [Cache Rule](/cache/how-to/cache-rules/) with an [Edge Cache TTL](/cache/how-to/cache-rules/settings/#edge-ttl) setting that ignores origin cache-control overrides both directives. Refer to [CDN-Cache-Control](/cache/concepts/cdn-cache-control/) for the precedence rules.
- **`no-cache`, `max-age=0`, or `s-maxage=0` in these headers do not produce `BYPASS`.** They produce `MISS` on the first request, then [`REVALIDATED`](/cache/concepts/cache-responses/#revalidated) or [`EXPIRED`](/cache/concepts/cache-responses/#expired) — check under [Repeated MISS](#repeated-miss--cacheable-but-not-in-cache) instead.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pointer sends people the wrong way. Repeated MISS is about cache key variance and eviction. Someone who lands here sees MISS once and then REVALIDATED on every request after, so that section has nothing for them and they'll go dig through cache key config for a response that's caching fine.

"Confirm the response reaches cache" is the right target, its second bullet already covers the REVALIDATED and EXPIRED outcome. Or drop the pointer, since the bullet already says what to expect.


- **The response exceeds the [cacheable size limit](/cache/concepts/default-cache-behavior/#cacheable-size-limits) for your plan.** Split the object into smaller assets, or move to a plan with a higher limit. [R2](/r2/) is an origin storage alternative — it does not raise the CDN cacheable size limit.
- **The origin returned `no-store` or bare `private` in a `Cloudflare-CDN-Cache-Control` or `CDN-Cache-Control` header.** Cloudflare evaluates these headers ahead of `Cache-Control`, in the precedence `Cloudflare-CDN-Cache-Control` > `CDN-Cache-Control` > `Cache-Control`. An origin returning `Cache-Control: public, max-age=3600` together with `CDN-Cache-Control: no-store` produces `BYPASS`. Cloudflare does not forward `Cloudflare-CDN-Cache-Control` to the client, so it is not visible in the response — if you see `BYPASS` without a `CDN-Cache-Control` header, check what the origin actually sent, or have the origin drop the header and retest. A [Cache Rule](/cache/how-to/cache-rules/) with an [Edge Cache TTL](/cache/how-to/cache-rules/settings/#edge-ttl) setting that ignores origin cache-control overrides both directives. Refer to [CDN-Cache-Control](/cache/concepts/cdn-cache-control/) for the precedence rules.
- **`no-cache`, `max-age=0`, or `s-maxage=0` in these headers do not produce `BYPASS`.** They produce `MISS` on the first request, then [`REVALIDATED`](/cache/concepts/cache-responses/#revalidated) or [`EXPIRED`](/cache/concepts/cache-responses/#expired) — check under [Repeated MISS](#repeated-miss--cacheable-but-not-in-cache) instead.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"these headers" only resolves if you've read the bullet above, which won't happen for someone scanning. Worth naming them here. Helps twice over, since a "not this" item sitting in a list of BYPASS causes is easy to skim wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

product:cache Issues or PRs related to Cache size/xs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants