Focused follow-up · 16 Sep 2026
Locating the serving layer
When an old or unexpected response appears, use scoped observations to separate browser HTTP cache, service worker, history/bfcache, intermediary, and origin behavior.
No live layer attribution was obtained
curl and browser executables were absent, the supplied run had no authorized endpoint, and a Node loopback listener was rejected with EPERM. The matrices and commands below are an explicitly labeled, source-grounded expected probe. They are not measurements of a production browser, CDN, origin, or shared cache.
Bottom line
Provenance is a sequence of scoped observations, not a conclusion from “old bytes,” 200, a DevTools label, or one missing header.
- Ask whether a new fetch happened. A
pageshowreactivation withpersisted: trueand no request supports a history/bfcache path, not HTTP-cache reuse. A controlled service-worker log can instead show that a worker returned aCacheentry or synthesized a response. Only after those paths are excluded does a normal-repeat versus fresh-profile/disabled-browser-cache comparison support a browser HTTP-cache explanation. - Seek positive evidence from a named intermediary. A
Cache-Statusmember naming the test cache and reportinghitis the strongest protocol-level statement that this cache satisfied the request without forwarding.Agecorroborates when present;Viaidentifies forwarding intermediaries, not cache hits. Missing fields are unknown, not “no cache.” - Corroborate with a controlled origin. Keep URL, method, host, redirect behavior, and client inputs fixed; change only an out-of-band origin phase from marker A to marker B. An origin counter/log plus a direct-origin route can show whether that controlled origin received a request. It cannot erase or disprove a response held by another layer.
- Scope every conclusion. A positive instrumented observation identifies a layer for one client, URL, request, time, and topology. It does not prove a global absence of caches or cross-user leakage.
1 · Layer boundaries
| Layer | Boundary | HTTP cache? | Positive observation to seek |
|---|---|---|---|
| Browser HTTP cache | The user agent’s private HTTP response cache. It can satisfy a request without a network transfer. RFC 9111 calls this a private cache when dedicated to one user. | Yes | A controlled normal-repeat/fresh-context difference, a browser cache source/transfer record, and the same marker/headers under that browser condition. |
| Service worker and Cache API | A service worker is script-controlled fetch handling. It can synthesize a Response, return caches.match(...), or call fetch() and let a later HTTP-cache/intermediary path run. Named Cache objects are origin-scoped, script-managed, and isolated from the browser HTTP cache. | No for the worker program and Cache API store; a worker may invoke an HTTP cache. | Registration/scope/control state plus an instrumented worker event log showing Cache hit/miss and whether respondWith returned the response. Chrome’s Network timing can show service-worker preparation/request-to-worker, but that is Chrome-specific. |
| History / bfcache | Session history can reactivate an earlier Document and persisted state. The bfcache keeps a document alive for history traversal. It can repaint old DOM without fetching the URL. | No | Back/forward versus reload, a test-only pageshow persisted value, page lifecycle log, and absence/presence of a new document request. |
| Intermediary | A reverse proxy, CDN, or other shared cache between client and origin. It may be one hop among several and may expose optional diagnostics. | Yes | A diagnostic member naming the intended cache, its Cache-Status result, Age when present, Via, documented edge/POP field, marker, and origin log correlation. |
| Origin | The controlled HTTP application/server that produces the marker and records request time/counter. It may use application/database caches internally; those are not established by HTTP-cache headers. | Not inherently | The origin access log/request counter and the marker/status from a direct-origin route or a named intermediary forward. |
RFC 9111 §6 explicitly separates browser history and other application caching from HTTP-cache requirements. The Fetch Standard’s layer description likewise distinguishes API, service-worker, and network/cache layers. A worker calling fetch() does not make the eventual response an HTTP-cache hit; it only means another layer still needs to be inspected.
2 · Controlled path (planned, not executed)
Exact lab target and topology
Use a reserved, non-production test name and synthetic data only:
Client: GET https://probe.example.test/layer-probe
method = GET; target URI exactly /layer-probe; Host/SNI = probe.example.test
Edge path: client -> named test reverse proxy/cache `edge-test` -> origin
Direct control: same URL/Host/SNI, resolved to the authorized origin address with --resolve;
no edge hop
Redirect policy: expected 200 with no redirect; do not follow an unexpected 3xx in the
attribution run; save status and Location, then test the new target separately.
Client state: no cookies, no Authorization, no extensions, fixed Accept, no query string,
no request-body variation; use a fresh browser profile for cold-client runs.
probe.example.test and ORIGIN_IP below are placeholders for an operator’s authorized lab; they were not contacted. The origin must expose an out-of-band phase switch or deployment toggle. It must not derive the marker from the URL, a cookie, an identity, or a request header. For phase A and then phase B, keep method, URI, host, redirect behavior, response policy, and response shape constant; change only the origin phase.
The controlled origin response should contain a redacted test marker such as X-Variant-Marker: A (then B) and a body/log record such as phase=A; origin_counter=17; request_id=<redacted>. The counter is a server-side observation, not a user-visible identity. Log, in UTC, the request ID, method, host, exact path, response phase, status, and counter; never log credentials or personal data. The test response may use a fixed, explicitly documented public test policy such as Cache-Control: public, max-age=60; capture it but do not treat policy as proof that any layer stored the response.
Capture, at the intended hop and in the direct-origin control, the status/redirect chain and the response fields Cache-Control, Age, Cache-Status, Via, and X-Variant-Marker. Also save the body marker, origin counter/log line, client state, UTC timestamp, and edge/POP identifier if the deployment documents one. A provider-specific field is useful only with that provider’s current documentation; this run selected no vendor field.
Warm-up and comparison order
- Clear the named edge test cache or record a known cold key; reset the origin counter and set phase A.
- Request the direct-origin control once. Record that it returns A and increments the origin counter; this does not warm the edge.
- Request the edge URL once from a normal client. Record the cold response, edge diagnostics, and the matching origin log entry. This is the only warm-up for the edge key.
- Flip only the origin phase to B out of band. Do not change URL, host, method, redirects, policy, or client inputs.
- Repeat the edge URL in the same client. Record whether a browser request occurred, worker state, marker, all captured headers, and the origin counter.
- Repeat from a fresh client/profile with no service-worker registration. This removes the first client’s browser HTTP cache/history state but intentionally does not clear the edge.
- Request the same URL with a direct-origin route using the same Host/SNI. Record B and the origin counter. Compare this control only with the edge response from the same phase and timestamp.
- Run the service-worker and history/bfcache subtests below as separate runs, after clearing their own state. Do not combine an uncontrolled worker, back navigation, and an edge warm-up in one A/B test.
Unexecuted direct-client template
curl is absent here. If an authorized lab supplies it, these are copyable templates; replace ORIGIN_IP and the lab phase switch, and do not print bodies containing anything sensitive.
URL='https://probe.example.test/layer-probe'
ORIGIN_IP='203.0.113.10' # authorized lab address only
OUT="/tmp/layer-probe-$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$OUT"
# R1: cold edge, origin phase A (no redirect following)
curl -sS --noproxy '*' --max-redirs 0 -D "$OUT/edge-A.headers" -o "$OUT/edge-A.body" "$URL"
# Flip only the origin phase from A to B, then R2: same edge client/URL.
curl -sS --noproxy '*' --max-redirs 0 -D "$OUT/edge-B-repeat.headers" \
-o "$OUT/edge-B-repeat.body" "$URL"
# R3: direct origin, same URL and Host/SNI, bypassing the edge and any proxy.
curl -sS --noproxy '*' --resolve "probe.example.test:443:$ORIGIN_IP" --max-redirs 0 \
-D "$OUT/origin-B.headers" -o "$OUT/origin-B.body" "$URL"
# Print only non-sensitive status/diagnostic fields.
awk 'BEGIN{IGNORECASE=1} /^(HTTP\/|cache-control:|age:|cache-status:|via:|x-variant-marker:|location:)/ {print FILENAME ": " $0}' \
"$OUT"/*.headers
printf '\nBody hashes:\n'; sha256sum "$OUT"/*.body
No live response, marker, Age, Cache-Status, Via, or origin counter was captured by this run. A direct client is not a browser and does not reproduce browser history, service-worker control, browser cache partitioning, or the user’s proxy path.
3 · Expected outcome matrix Not measurements
The following is the deterministic expected interpretation of the controlled path. It is not a claim about any particular CDN or browser.
| Sequence | Expected record | Scoped interpretation | Not enough to conclude |
|---|---|---|---|
| Direct origin in phase A | Marker A; origin counter increments; direct-origin log has the request. | The controlled origin can emit A and received this direct request. | That the edge is cold, or that no other layer has an earlier response. |
| Edge R1 while cold | Marker A; origin counter/log correlation; a named edge may report a forward/miss. | The intended path returned A; if the named edge says it forwarded and the origin log matches, that edge forwarded this request. | That the edge stored the response unless its diagnostic/configuration or a later repeat establishes it. |
| Same edge URL after origin flips to B | Marker A + named Cache-Status hit + counter unchanged: strong evidence the named edge satisfied this request. Marker B + named forward/counter increment: evidence the request went onward and the origin response was used. | A positive result is scoped to the named edge and this key/POP/time. | An absent diagnostic, a browser no-request row, or a 200 alone identifies the source. |
| Fresh client to the still-warm edge | Marker A with named edge hit/age and no origin increment isolates the old response from the first browser’s HTTP cache; marker B with origin increment shows no reuse on this path. | A fresh client removes one browser state, not every cache partition or POP. | Global absence of a shared cache, or behavior in another region/client topology. |
| Direct origin after flip | Marker B and a new origin log/counter entry. | The controlled origin currently returns B and saw this request. | That an edge/browser cannot still display A. |
| Controlled worker with Cache API entry | Worker is controlling the client; worker log says Cache.match hit; response marker is the seeded A; no origin request for that fetch. | This worker/Cache API supplied the response in this client. | That the browser HTTP cache or edge is empty; the worker could have seeded the entry from an earlier network response. |
Worker registered but Cache.match miss and fetch() path | Worker log says miss/forward; DevTools may show service-worker timing; then inspect downstream response and origin/edge evidence. | The worker handled the fetch and delegated it. | That fetch() reached the network; it may use browser HTTP cache or an intermediary. |
| Back/forward after phase changes | Old DOM/marker, no new document request, and pageshow.persisted === true. | A persisted history/bfcache reactivation explains the display. | That the original bytes came from HTTP cache, or that the intermediary was not involved on the earlier load. |
| Real reload/new navigation after the back test | New request record, then marker/headers/counter identify the next path. | A reload is a separate observation from history restoration. | That a reload bypasses every cache, or that it reaches the same POP as another client. |
4 · Required comparison matrix
| Layer/probe | Controlled comparison | Record | Establishes | Cannot establish |
|---|---|---|---|---|
| Browser HTTP cache | Normal repeat in one profile versus a fresh profile; then repeat with Chrome DevTools Disable cache and, separately, Clear browser cache. Keep service workers unregistered and avoid back/forward navigation. | Whether a Network row exists; Chrome transfer/source label if shown; status; marker/body; captured response fields; profile, DevTools, and timestamp state. | A browser-observable difference under the stated browser condition. A repeat that disappears only when that browser cache is cleared/disabled supports private HTTP-cache involvement. | CDN/origin storage, another client, bfcache/history, service-worker/Cache API, or production-wide behavior. Disable cache changes the experiment and is not a universal “all caches off” switch. |
| Service worker / Cache API | Controlled page with an active matching registration and a seeded named Cache versus an unregistered/uncontrolled fresh client with site data cleared. Run a Cache.match hit and a logged miss/delegate path separately. | Registration scope/state; navigator.serviceWorker.controller; worker event log/message; cache name and match result; Network initiator/timing; marker/status; edge/origin records. | Whether the instrumented worker handled this request and whether its instrumented Cache API lookup returned the response. | HTTP-cache semantics, a downstream fetch() source, another tab/client, an uninstrumented worker, or absence of a stale entry under a different Cache API name/options. Cache API keys/options are not HTTP cache keys. |
| History / bfcache | Load phase A, navigate to a same-origin control page, flip origin to B, use Back/Forward, then perform a real reload/new navigation. No service worker. | pageshow/pagehide and persisted; navigation type if exposed; DOM marker; URL/history state; whether a new request row and origin log entry occurred. | That a persisted session-history/bfcache reactivation can explain an old display without a new fetch; a reload is a distinct navigation observation. | That the bytes came from HTTP cache, that an intermediary was not involved on the original load, or that every browser treats DevTools/history labels identically. |
| Intermediary | Warm the named edge with A; flip origin to B; repeat at the same URL/host/POP where possible; compare with a direct-origin request using the same Host/SNI. Use a fresh client to avoid browser state. | Age, Cache-Status, Via, documented provider/POP field, marker, status, redirect chain, timestamps, origin counter/log, and topology. | A positive Cache-Status member for the named cache: hit means that cache says it satisfied the request without forwarding; fwd describes its forward path. Marker A plus that hit and an unchanged origin counter is scoped evidence for that cache. | Hidden/uninstrumented hops, browser layers, other POPs, cache partitioning, request collapsing, or anything inferred from an absent Age/Cache-Status. Via is a forwarding-path signal, not a hit indicator. |
| Origin | Edge path versus authorized origin-only route, same URL/Host/SNI where possible; reset/record counter and flip only the origin phase. | Origin request ID/time/method/host/path/counter; emitted marker/status/headers; redirect chain; edge diagnostic correlation. | Whether the controlled origin received that test request and what it emitted at that time. | That no browser/intermediary/service worker retained an earlier response, that a direct route has production topology, or that an origin application cache did not supply its own old data. |
5 · Reader-ready decision procedure
- Did this client make a new request?
- No, and
pageshow.persisted=true/ back-forward reactivation / old DOM remains: history or bfcache is a sufficient explanation for this display. It says nothing about where the original bytes came from. - No, and a matching service worker controls the client: inspect the worker log for a Cache API hit, synthesized response, or delegated fetch. If delegated, continue to downstream layers; do not call it an HTTP hit.
- No, and a fresh profile/unregistered worker differs from a normal repeat: browser HTTP-cache involvement is supported under that browser condition.
- No, none of the above: the result is unknown; application state, prerendering, another browser optimization, or an unrecorded request remains possible.
- Yes: inspect service-worker timing/control and worker logs; attribute only the worker’s handling. Then inspect a named intermediary’s
Cache-Status/documented edge record and compare the marker with the origin log/counter. - No positive signal on the new request: the topology is unknown. Repeat with a fresh client, direct control, fixed URL/host/redirects, and an instrumented named intermediary.
- No, and
What this proves: a positive, instrumented observation can identify a layer for one client, URL, request, time, and topology; a controlled origin log can establish receipt; a named Cache-Status can establish the named cache’s own report; a pageshow.persisted/lifecycle record can separate history restoration from an HTTP-cache request; a worker log can establish its own Cache API decision.
What this does not prove: a missing request is automatically a browser HTTP-cache hit; a missing Age/Cache-Status means origin contact; a DevTools source label is a cross-browser standard; a direct curl path equals a browser/CDN path; one clean A/B excludes leakage; a 200, 304, old body, or Via alone identifies the producer; a marker absent from a response means the marker was not stripped or rewritten.
6 · Small diagnostic/probe checklist
- Use synthetic A/B markers and a server-side counter; never put credentials or personal data in the probe body, URL, logs, or headers.
- Freeze method, exact target URI, host/SNI, redirects, request headers, cookies/auth state, client profile, and POP as far as the deployment permits.
- Record whether a request occurred before interpreting a browser source label; keep back/forward, reload, worker, and HTTP-cache cases as separate tests.
- At the intended intermediary, capture
Cache-Status,Age,Via, status, redirect chain, marker, and any documented edge/POP field. - Correlate the edge result with a direct-origin route and UTC origin counter/log, but do not treat the direct route as the production topology.
- Run serialized and concurrent cases separately; request collapsing can make an origin count lower than client request count without proving a hit.
- Repeat at a fresh client and, where possible, another POP or partition. A clean result at one path does not prove the absence of leakage elsewhere.
7 · Claim classification
| Class | Claim used here | Evidence/source or status |
|---|---|---|
| Observed | At 2026-09-16T14:02:40Z, curl, Chromium, Chrome, Firefox, and chromium-browser were absent. Node was available; a local 127.0.0.1 listener failed with EPERM. No authorized endpoint or browser session was supplied. | Runner shell capability check. This is the only live execution result; it is not a cache measurement. |
| Normative | RFC 9111 defines HTTP/private/shared caches and explicitly separates browser history/application caches (§§1, 2, 6). A stored response reused without validation must generate Age; absence of Age does not imply origin contact (§§4, 5.1). | RFC 9111 §2, §4, §5.1, §6. |
| Normative | Cache-Status is optional/configurable; for the named cache, hit means the request was satisfied without forwarding, while fwd, fwd-status, stored, and collapsed describe that cache’s handling when present. | RFC 9211 §2, §§2.1–2.6. |
| Normative | Via members represent intermediaries that forwarded a message and are appended in forwarding order; it is not a cache-hit field. | RFC 9110 §7.6.3. |
| Normative | Service-worker Handle Fetch is a fetch-handling entry point; named Cache objects are script-managed, origin-associated, and isolated from the browser HTTP cache. HTML defines session-history traversal, persisted history state, page-transition events, and bfcache document reactivation. | Service Workers §4.5, Handle Fetch, §5, Caches, HTML §7.4.3, §7.4.6.5, and document lifecycle. |
| Browser-facing | Chrome Network records requests, status, initiator, size, and time; its Network reference documents Disable cache/Clear browser cache and service-worker timing phases. Chrome Application exposes service workers, Cache Storage, and a bfcache test. | Chrome-specific, not universal: Network panel, Network features reference, Application panel, and bfcache test. |
| Vendor/configuration-specific | A field such as a named edge Cache-Status member or a POP identifier is meaningful only if that deployment emits and documents it. No CDN product or proprietary field was selected or measured here. | Configuration requirement; do not generalize X-Cache-style fields. |
| Inference/recommendation | Use a fresh client, controlled worker state, explicit history/reload comparison, named-hop diagnostics, direct-origin control, and origin counter together. Treat only positive, scoped evidence as attribution. | Recommended method derived from the standards, browser docs, and the unexecuted matrix; no live production inference. |
8 · Header-example check
All concrete header examples in this report were checked against the pool’s primary-documentation workflow on 16 Sep 2026 UTC. Direction and context are explicit.
| Exact example | Direction/context | Verdict and source | Proves | Does not prove |
|---|---|---|---|---|
Cache-Control: public, max-age=60 | Response from https://probe.example.test/layer-probe; fixed public lab phase A/B. | Correct response-directive example for a controlled cacheable test response under RFC 9111 §3, §5.2.2.1, and §5.2.2.9. | The origin selected this response policy. | That a browser/intermediary stored or reused it, or that the body is safe outside the lab. |
X-Variant-Marker: A / X-Variant-Marker: B | Response from the controlled origin or instrumented worker; test-only, redacted marker. | Valid custom instrumentation; no standard HTTP-cache semantics. | Which marker the observed response carried. | Which layer supplied it, whether a layer rewrote/stripped it, or any user identity. |
Age: 3 | Response observed by the direct client. | Valid Age field example; RFC 9111 §§4.2.3, 5.1. | Presence is evidence the response was not generated or validated by the origin for that request; it is cache-age evidence. | Which cache/POP added it, or anything when it is absent. |
Cache-Status: edge-test; hit | Response from the named intermediary. | Valid RFC 9211-shaped example; RFC 9211 §§2, 2.1. | The named cache reports satisfying the request without forwarding. | Browser state, hidden hops, global cache absence, or safety of the body. |
Cache-Status: edge-test; fwd=uri-miss; fwd-status=200; stored | Response from the named intermediary after a controlled forward. | Valid diagnostic shape; RFC 9211 §§2.2–2.5. | The named cache reports its forward reason, next-hop status, and storage result. | That the next hop was the origin, or that other caches behaved the same. |
Via: 1.1 edge-test | Response from the controlled edge path. | Valid illustrative Via value; RFC 9110 §7.6.3. | An intermediate protocol/recipient is identified in the response path. | A complete hop list, a cache hit, or origin contact on this request. |
The marker values and edge-test name are local test labels, not vendor claims. The Cache-Status examples use the RFC’s standardized parameter meanings; a production field is useful only when emitted by the intended cache and retained through the path.
9 · Limits and unresolved edge cases
- Absent
AgeorCache-Status: RFC 9111 requiresAgewhen a stored response is used without validation, but expressly says lack ofAgedoes not imply origin contact. RFC 9211 says caches decide when to addCache-Status; omission is not evidence of absence. - DevTools “Disable cache”: the Chrome control disables the browser cache while DevTools is open; it changes the experiment. It is not a global bypass for service workers, Cache API, history/bfcache, an intermediary, another profile, or another POP.
- Service-worker/Cache API keys: named Cache objects are not the HTTP cache. Their
Cache.matchrequest/options and script policy can select a response independently; a worker’s delegatedfetch()can then hit another layer. - History/bfcache: a no-request old display, even with an old marker, is not HTTP-cache evidence. It can be a restored document/state; the
pageshowsignal identifies a browser lifecycle path, not the original response source. - Direct-client topology: direct
curl, a fresh browser, and a user’s browser can differ in DNS, proxy, TLS termination, HTTP version, cookies/auth state, cache partition, connection reuse, and POP. Same URL text is not the same path. - Redirects: a cached redirect or a service-worker response can move the effective request to a different URL/host. The planned run expects no redirect; any 3xx must be recorded as its own response and the follow-up target tested separately.
- Partitioning: browsers and managed intermediaries can partition storage by site, top-level context, tenant, or POP. A fresh profile or one client does not test every partition.
- Request collapsing: concurrent requests can share one forward. An origin counter lower than client request count does not by itself mean a hit; inspect a named
collapseddiagnostic if available and run serialized and concurrent cases separately. - Other POPs/hops: a positive edge observation applies only to the named cache instance/path. A clean result at one POP cannot rule out an old entry at another POP, an enterprise proxy, or a different route.
- One A/B test cannot prove absence of leakage: a marker mismatch is a strong failure for the exact tested path. A correct B response only says that this one key, client state, time, and topology produced B. It does not test alternate query/redirect/resource keys, concurrent races, cache partitions, other POPs, or uninstrumented layers.
- Marker integrity: a custom marker may be removed, rewritten, or generated by an application layer. Preserve a body marker and origin log, and treat marker absence as unknown rather than proof of a miss.
- Worker/lifecycle races: registration activation,
clients.claim(), a page becoming controlled, cache population, reload, and back/forward restoration are asynchronous. Record registration state and run each subtest from a fresh, known state.
Sources and retrieval ledger
Retrieved/cross-checked 16 Sep 2026 UTC; primary standards are listed first. No vendor documentation was used for a universal claim. A named provider’s field/configuration should be added only when that provider and deployment are identified.
Primary standards
- RFC 9111 — HTTP Caching §2, §4, §4.2.3, §5.1, §6.
- RFC 9211 — Cache-Status §2, especially §§2.1–2.6.
- RFC 9110 — HTTP Semantics §7.6.3, Via.
- Fetch Living Standard — layer division and HTTP-network-or-cache fetch, retrieved as the 2026-09-02 living revision shown by the source.
- Service Workers Nightly — §4.5 Handle Fetch and §5 Caches / §5.2 lifetimes.
- HTML Living Standard — §7.4.3 reloading and traversing, §7.4.6.5 persisted history entry state, §7.2.7.6 PageTransitionEvent, and document lifecycle/bfcache.
Browser-facing cross-checks (Chrome-specific)
- Chrome DevTools Network panel: logging requests and request columns.
- Chrome DevTools Network features reference: Disable cache, Clear browser cache, service-worker timing phases, and sanitized HAR handling.
- Chrome DevTools Application panel: service workers, Cache Storage, storage, and bfcache tools.
- Chrome DevTools bfcache test: bfcache is distinct from browser/HTTP cache and how Chrome tests it.
- MDN HTTP caching: developer-facing cross-check for private/shared and browser/intermediary terminology; not used to override the RFCs.
- MDN Cache-Control: developer-facing cross-check for the test policy; not a layer-attribution proof.
Remaining questions
- Which authorized CDN/reverse-proxy product and POP topology should supply the named intermediary in the next live run?
- Can that deployment expose RFC 9211
Cache-Statusand an origin request ID without exposing credentials or personal data? - Which browser/version is in scope for the first browser capture, and can its DevTools export be sanitized?
- Does the target application install a worker, use navigation preload, or prerender pages that require separate control cases?