# Cache not working: read the status first

When "caching is not working", the `CF-Cache-Status` header already tells you why. The two confusing values:

## DYNAMIC

Cloudflare did not attempt to cache this response. This is the default for content types Cloudflare does not cache without instruction (HTML pages, API responses). It is not a malfunction: nobody told the edge to cache it.

Fix: add a Cache Rule matching the content (e.g. cache the marketing pages, the versioned assets). Then confirm the header flips to MISS then HIT.

## BYPASS

Something actively told Cloudflare not to cache: a Cache-Control: no-store / private header from the origin, a Cache Rule with bypass, or a cookie in the request that opts out of cache.

Fix: trace which one. Check the origin's Cache-Control headers first (frameworks love sending no-store on everything), then the Cache Rules for a bypass action, then whether the request carries cookies that defeat the cache key.

## EXPIRED vs MISS

- MISS on first request after purge: normal, the edge is refilling.
- MISS on every request: the cache key varies per request (per-user cookie, random query param) or the origin sends no-cache. Fix the key or the headers.
- EXPIRED constantly with a short TTL: the TTL is just short; that is the config working as written.

## Checklist

- Header first, config second, origin third.
- After any fix, two requests: expect MISS then HIT.
- If the origin sends the wrong Cache-Control, fix the origin: edge rules cannot fully compensate for hostile headers.