Shaduf.Research preview
HTTP Cache Field Guide/What does immutable change for a fresh response?

Dated report · Cache-Control immutable · 28 Oct 2026

What immutable means for a fresh response

A narrow standards and documentation review of the response directive, its freshness boundary, explicit user checks, and the browser-facing reload caveat.

Source review complete; no endpoint or browser testing. Sources were checked on 28 Oct 2026. No cache, provider, response header, or browser implementation was exercised.

Finding

immutable is a response Cache-Control extension that asserts the representation will not change during its freshness lifetime. For a stored response that is still fresh, clients SHOULD NOT send conditional requests (including on reload), unless the user explicitly overrides that behavior. Once stale, the response returns to ordinary revalidation rules. The extension does not choose the freshness lifetime: in Cache-Control: max-age=31536000, immutable, max-age supplies the example’s year-long lifetime.

Normative semantics: RFC 8246

RFC 8246 §2 defines immutable as a response directive, not a request directive. It says that a client with a fresh stored immutable response SHOULD NOT issue a conditional request unless explicitly overridden by the user (the RFC gives force reload as an example). The extension is limited to the response’s freshness lifetime. When the response is stale, it SHOULD be revalidated as it would without immutable. These are normative recommendations; they do not establish support or uniform behavior across all user agents.

The same purpose applies to intermediaries: they SHOULD skip conditional revalidation for a fresh immutable response, unless a client signal indicates validation is needed. RFC 8246 gives request Cache-Control: no-cache as an example. If an intermediary bypasses validation, §2.1 leaves it to the intermediary to decide whether a client receives a 304 or 200 based on the request headers it received. Therefore, the response directive alone does not determine a client-visible status code.

RFC 8246 §2 also says the extension takes no arguments; supplied arguments have no meaning and MUST be ignored; duplicate instances are equivalent to one; and the directive has no effect in a request. Section 3 recommends that clients ignore it for resources outside an authenticated context such as HTTPS, because unauthenticated resources are more exposed to cache corruption.

Three cases that are easy to confuse

CaseDocumented or normative behaviorLimit
Fresh response; normal use or reloadRFC 8246 §2 recommends that a client not send a conditional request for a fresh immutable response, including on reload.The recommendation lasts only for the applicable freshness lifetime.
Response has become staleRFC 8246 says to return to the ordinary revalidation behavior that would apply without immutable.Stale-use extensions, prohibitions, validators, request signals, and cache implementation policy are separate questions.
User explicitly asks to check againRFC 8246 §3 says user agents SHOULD ignore immutable for force reloads, which are typically indicated by request no-cache attributes. Section 2.1 says an intermediary should not skip validation when the client indicates it is needed.RFC 9111 §5.2.1 treats request directives as advisory to caches. The request does not guarantee an origin trip, a particular response code, or identical behavior in every browser/cache.

MDN’s current guide illustrates a normal reload with request Cache-Control: max-age=0 and validators such as If-None-Match. It illustrates a force reload with request Cache-Control: no-cache and Pragma: no-cache, without conditional validators. MDN notes that Chrome, Edge, and Firefox requests are similar to its example while Safari differs. These are documentation examples, not a guarantee for every browser version or response.

Freshness comes from the lifetime policy

HTTP/1.1 200 OK
Cache-Control: max-age=31536000, immutable

Here max-age=31536000 supplies an explicit one-year freshness lifetime for a private cache; immutable supplies no lifetime. If s-maxage were present, RFC 9111 §5.2.2.10 would give it precedence for shared caches. The example contains no public directive: do not infer shared-cache permission from immutable.

For a static file, keep the representation unchanged at its versioned URL for the stated lifetime and publish changed bytes at a different URL, such as one containing a version or content hash. The new URL is a distinct target URI; it is not an instruction to delete a previously stored response for the old URL.

Keep the mechanisms separate

QuestionRelevant controlWhat immutable contributes
How long is a stored response fresh?Response max-age, shared-cache s-maxage, or other freshness rules such as Expires.No freshness lifetime of its own.
May a cache store or share it?RFC 9111 storage rules and directives such as no-store, private, and, where appropriate, public.No storage or privacy permission.
Which request variant matches?At minimum method and target URI, with Vary and any cache-specific key configuration.Not a cache-key component.
How is an old URI removed?Expiry, validation, or an authorized cache-specific purge/invalidation mechanism.No purge or delete instruction.

Browser-facing caveat: scope the claim

At retrieval on 28 Oct 2026, MDN’s HTTP caching guide said Chrome changed its implementation so it does not revalidate subresources on reload, rather than implementing that part of the behavior through immutable. The guide links to a Chromium Blog post dated 26 Jan 2017. That post describes a Chrome reload design that validates the main resource and reuses cached resources in the rest of the page load.

This is a current MDN documentation statement plus a historical browser-project explanation. It is specifically about Chrome and reload subresources. It does not establish current behavior for all Chrome versions, force reloads, other browsers, response classes, intermediaries, or all uses of immutable. No browser was run for this report.

Scope and uncertainty

  • The standards text establishes a freshness-bounded revalidation recommendation and an explicit user-override path; it does not establish browser compatibility or intermediary support. RFC 8246 also recommends ignoring the directive for unauthenticated resources; it is not an integrity mechanism.
  • The MDN Chrome caveat gives no version range in the cited passage. Its linked Chromium Blog post is dated 2017-01-26; this review does not establish whether later releases changed normal or force-reload details.
  • No endpoint headers, cache hits, browser requests, network traces, provider TTLs, or versioned-asset deployment were observed. No product configuration or adoption prevalence is inferred.
  • Cache-key extensions, stale-use extensions, and named-provider policies are outside this report’s scope.

Sources

All sources below were checked on 28 Oct 2026. RFC text is normative where specified; MDN is browser-facing documentation, and the Chromium Blog is historical project context.

Search published pools, pages, reports, and evidence.