Shaduf.Research preview
HTTP Cache Field Guide/304 response selection

Guide · RFC 9111 §4.3.4 · 22 Oct 2026

Which stored response does a 304 update?

A 304 does not select every response for a URL. First form the request-compatible candidate set, then apply the first matching validator rule.

Standards-only guide with synthetic examples. No cache, endpoint, browser, provider, or implementation was tested.

Quick answer

Under RFC 9111 §4.3.4, a stale response can still be a candidate for a 304 update. A matching strong validator can select every matching candidate; weak validators select only the most recent matching candidate, and only when the 304 has no strong validator. With no validator at all, the exception applies only to a single candidate that also has no validator.

Selection is a sequence: qualify stored responses for the request, take the first applicable validator branch, then update metadata for selected entries.

  1. 1 · Candidate set
    Same target URI and reusable method; matching Vary fields; honor the no-cache validation rule.
  2. 2 · Strong validator?
    Select all candidates sharing a 304 strong validator. No strong match means stop.
  3. 3 · Otherwise weak?
    If there is no strong validator, select only the most recent matching weak candidate.
  4. 4 · No validator?
    Only one candidate with no validator can qualify; update its headers from the 304.
Freshness is omitted only when forming §4.3.4's initial set; it does not make unrelated URI, method, or variant entries candidates.

1. Form the initial candidate set

Start with responses that could have been chosen for the request under RFC 9111 §4, except for its final gate requiring the response to be fresh, permitted stale, or already validated. Keep the target URI and method reuse checks, request fields nominated by Vary, and the successful-validation condition for no-cache entries. This means a stale entry can still be considered for freshening; a different URI or incompatible request variant cannot. A Vary: * entry never matches.

2. Take the first applicable validator branch

Strong validator present

The 304's strong validator(s) select every initial-set response with one of the same strong validators. If none match, the cache MUST NOT update any stored response from that 304; it does not fall through to weak matching.

No strong, but a matching weak validator

Select the most recent matching stored response, determined by its Date field—not every weak match.

No validator of any kind

Only if the initial set contains exactly one response, and that response also has no validator, can this branch identify an entry.

For ETags, an unprefixed tag is strong by default and W/ marks a weak tag. A Last-Modified time is implicitly weak unless RFC 9110 §8.8.2.2's conditions let the recipient deduce that it is strong. See RFC 9110 §8.8.1, §8.8.2.2, and §8.8.3.

A synthetic selection example

Assume a cache validates GET /manual; every row matches the request's URI, method, and Vary fields. All four entries are stale, which does not exclude them from the initial set. Dates are shown only to resolve “most recent.”

EntryStored ETagDate
A"rev-7" (strong)10:00
B"rev-7" (strong)10:02
CW/"group-2" (weak)10:03
DW/"group-1" (weak)10:01
  • A 304 with ETag: "rev-7" and Cache-Control: max-age=600 selects A and B. The freshness field updates their metadata; the strong validator does not select C or D.
  • A different 304 with only ETag: W/"group-1" selects D. If A and B instead both had that weak tag, it would select only the more recent one by Date.
  • A 304 with no validator selects none from this four-entry set. A separate initial set of one validator-less response would meet the narrow exception.

These are alternative synthetic outcomes, not a claim about a particular cache's stored entries or behavior.

304 means metadata, not replacement bytes

RFC 9110 §15.4.5 says a 304 response cannot contain content or trailers. Its headers can carry metadata used to update the selected stored response. RFC 9111 §4.3.4 requires updating selected stored header fields with fields provided in the 304, as described in §3.2 (including its exclusions). A cache or client can then use the already-stored body; those bytes were not transferred in the 304. RFC 9110 §15.4.5 · RFC 9111 §4.3.3.

What the standard does not prove

This is a reading of standards text, not a test of a product. A bare 304 observation does not establish which hop supplied it, which stored entry an implementation updated, whether a page visibly changed, or whether missing bytes were restored. Those questions need a relevant trace and/or implementation evidence.

Checkable sources

Search published pools, pages, reports, and evidence.