Cache-Control no-store + max-age Conflict: How to Fix Caching Chaos
Diagnose and resolve contradictory cache directives that cause random hit/miss behavior.
When `no-store` appears together with `max-age` or `immutable`, caches and teams read the policy differently. This guide gives a deterministic fix path.
Tools in this guide
Symptoms
- Responses randomly switch between cache hit and origin fetch.
- CDN behavior differs from browser cache behavior for the same URL.
- Auth-related responses occasionally leak stale or wrong user state.
Root Cause
- `no-store` is combined with `max-age` / `immutable`, creating contradictory directives.
- `private` and shared cache expectations are mixed without explicit policy separation.
- Validator strategy (`ETag` / `Last-Modified`) is missing, forcing hard fallback after TTL.
Fix Steps
- Parse raw Cache-Control value and remove contradictory directives first.
- Split policy by response type: auth/session routes use strict no-store/private, static/API cacheable routes use explicit TTL.
- If stale serving is desired, add `stale-while-revalidate` and validator headers to control revalidation behavior.
Safe baseline for sensitive API responses
Cache-Control: private, no-store
Pragma: no-cacheRelated Tool Workflow
FAQ
Can no-store and max-age exist together?
Technically possible, but operationally contradictory and should be avoided.
When should I use stale-while-revalidate?
Use it for non-sensitive cacheable content where brief staleness is acceptable.