Cache-Control no-store with max-age: What It Means and What to Check

Interpret no-store, max-age, no-cache, private, and public with separate sensitive and public-response examples, then check the headers actually served.

Cache-Control: no-store, max-age=3600 is not undefined behavior. For this combination, a conforming cache must not store the response or reuse it for another request; the freshness lifetime does not override no-store.

Author: Evan•Published: March 19, 2026•Updated: September 29, 2026•3 min read

Tools in this guide

1. Read the combined header without guessing

Paste no-store, max-age=3600 into Cache-Control Parser. It contains a storage prohibition and a one-hour freshness value. Under RFC 9111, no-store applies to private and shared caches, so max-age provides no useful reuse lifetime here. This is redundant policy intent, not evidence that caches choose directives at random.

If the application and CDN disagree, capture the final response headers in browser developer tools, paste them into HTTP Headers Parser, and compare them with the origin configuration. Middleware or an edge rule may add or replace a header. A parser explains a pasted value; it cannot observe or verify the deployed cache. The separate must-understand exception in RFC 9111 §5.2.2.3 is outside this two-directive example.

2. Keep sensitive responses out of HTTP caches

For a test endpoint that returns an account statement or newly issued credential, use Cache-Control: no-store. Adding private is redundant for storage because no-store already covers shared and private caches. Do not remove no-store merely to improve hit rates or silence a warning.

If the intended policy is to allow a user’s browser cache but prohibit a shared cache, private has a different role. For example, private, no-cache permits private storage but requires successful validation before reuse. Use that only when storing the response on the user’s device is acceptable; it is not equivalent to no-store.

Neither private nor no-store replaces authentication, HTTPS, or cache access controls. They also do not purge a previously cached response on every device. A wrong-user response requires investigation of cache keys, authentication boundaries, and edge overrides; the presence of no-store plus max-age alone does not demonstrate that cause.

3. Give non-sensitive content a deliberate freshness policy

For a public release-notes JSON response whose representation is identical for every visitor, a possible policy is Cache-Control: public, max-age=300 with an ETag such as "release-v2". This allows caching, with a five-minute freshness lifetime subject to normal HTTP age calculations and other cache rules. Once stale, a cache can send If-None-Match to validate that representation.

Public permits shared storage, even in some cases that would otherwise prohibit it; private excludes shared storage. Do not apply the public example to a personalized response just because its URL looks static. Check cookies, Authorization handling, the representation, and the CDN’s cache key first.

If a public response may be stored but must be validated before every reuse, Cache-Control: no-cache with an ETag expresses that policy. No-cache does not mean “never store”; a successful validation is required before reuse. A changed representation normally needs a fresh response body instead of a 304.

4. Verify the deployed behavior with a disposable resource

Request the same test URL twice through the normal production path and record status, Cache-Control, Age if present, ETag, and any documented CDN cache-status field. Keep browser developer tools’ Disable cache option off for this observation; use an ordinary request rather than a forced reload when checking reuse.

For the no-store example, the expected policy is no storage or reuse by HTTP caches. For the public example, repeat while fresh, then after its lifetime and inspect whether validation occurs. A missing Age header or two 200 responses alone does not prove whether a cache was used; combine header evidence with the CDN or origin logs.

If you change a response from public caching to no-store, investigate and invalidate existing shared-cache entries as required by the platform. The new header only takes effect when received. Keep the test payload non-sensitive while checking this transition.

Read the HTTP caching definitions