HTTP Caching and Status Codes

How HTTP status codes interact with caching. Which codes are cacheable by default (RFC 9110), Cache-Control with status codes, and the 304 conditional request flow.

ZERO UPLOAD · ALL LOCAL
  1. Type a code number (e.g. 404) to find codes by number only, or a word (e.g. "timeout", "rate limit") to search names and detail content.
  2. Use the category pills (1xx–5xx) to browse codes by class when not searching.
  3. Click Details on any card to expand causes and resolution steps in a full-width panel below the row.
  4. Click Copy Markdown on an expanded card to copy a ready-to-paste summary for Jira tickets, GitHub issues, or Slack.

Cacheable by default under RFC 9110

  • 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, 501
  • 302, 307, 500, 502, 503, 504
  • revalidation response — no body, updates cached headers

404 and 410 being cacheable by default is a common surprise — a cached 404 can block a client from reaching a resource you create later at the same URL.

1XX INFORMATIONAL — 4 codes

100 Continue
RFC 9110
101 Switching Protocols
RFC 9110
102 Processing
RFC 2518
103 Early Hints
RFC 8297

2XX SUCCESS — 10 codes

200 OK
RFC 9110
201 Created
RFC 9110
202 Accepted
RFC 9110
203 Non-Authoritative Information
RFC 9110
204 No Content
RFC 9110
205 Reset Content
RFC 9110
206 Partial Content
RFC 9110
207 Multi-Status
RFC 4918
208 Already Reported
RFC 5842
226 IM Used
RFC 3229

3XX REDIRECTION — 8 codes

300 Multiple Choices
RFC 9110
301 Moved Permanently
RFC 9110
302 Found
RFC 9110
303 See Other
RFC 9110
304 Not Modified
RFC 9110
305 Use Proxy
RFC 9110
307 Temporary Redirect
RFC 9110
308 Permanent Redirect
RFC 9110

4XX CLIENT ERROR — 35 codes

400 Bad Request
RFC 9110
401 Unauthorized
RFC 9110
402 Payment Required
RFC 9110
403 Forbidden
RFC 9110
404 Not Found
RFC 9110
405 Method Not Allowed
RFC 9110
406 Not Acceptable
RFC 9110
407 Proxy Authentication Required
RFC 9110
408 Request Timeout
RFC 9110
409 Conflict
RFC 9110
410 Gone
RFC 9110
411 Length Required
RFC 9110
412 Precondition Failed
RFC 9110
413 Content Too Large
RFC 9110
414 URI Too Long
RFC 9110
415 Unsupported Media Type
RFC 9110
416 Range Not Satisfiable
RFC 9110
417 Expectation Failed
RFC 9110
418 I'm a Teapot (Unofficial)
RFC 2324
420 Enhance Your Calm (Unofficial)
Twitter
421 Misdirected Request
RFC 9110
422 Unprocessable Content
RFC 9110
423 Locked
RFC 4918
424 Failed Dependency
RFC 4918
425 Too Early
RFC 8470
426 Upgrade Required
RFC 9110
428 Precondition Required
RFC 6585
429 Too Many Requests
RFC 6585
431 Request Header Fields Too Large
RFC 6585
444 No Response (Unofficial)
nginx
451 Unavailable For Legal Reasons
RFC 7725
494 Request Header Too Large (Unofficial)
nginx
495 SSL Certificate Error (Unofficial)
nginx
496 SSL Certificate Required (Unofficial)
nginx
499 Client Closed Request (Unofficial)
nginx

5XX SERVER ERROR — 19 codes

500 Internal Server Error
RFC 9110
501 Not Implemented
RFC 9110
502 Bad Gateway
RFC 9110
503 Service Unavailable
RFC 9110
504 Gateway Timeout
RFC 9110
505 HTTP Version Not Supported
RFC 9110
506 Variant Also Negotiates
RFC 2295
507 Insufficient Storage
RFC 4918
508 Loop Detected
RFC 5842
510 Not Extended
RFC 2774
511 Network Authentication Required
RFC 6585
520 Web Server Returns an Unknown Error (Unofficial)
Cloudflare
521 Web Server Is Down (Unofficial)
Cloudflare
522 Connection Timed Out (Unofficial)
Cloudflare
523 Origin Is Unreachable (Unofficial)
Cloudflare
524 A Timeout Occurred (Unofficial)
Cloudflare
525 SSL Handshake Failed (Unofficial)
Cloudflare
526 Invalid SSL Certificate (Unofficial)
Cloudflare
527 Railgun Listener to Origin Error (Unofficial)
Cloudflare
No codes match your search.

HTTP Caching and Status Codes

HTTP caching interacts with status codes in ways that have lasting consequences. A cached response that should not be cached causes stale data to be served; a response that should be cached but is not wastes bandwidth and increases server load. The HTTP specification in RFC 9110 defines which status codes are cacheable by default and which require explicit Cache-Control headers to enable caching.1 Knowing these defaults prevents costly surprises: a 404 response is cacheable by default, so caching a 404 without Cache-Control: no-store means a client may serve a stale "not found" page for a resource you subsequently create. This guide covers the caching semantics of the most operationally significant status codes, grounded in RFC 9110.

Which codes are cacheable by default under RFC 9110

RFC 9110 defines a specific set of status codes as cacheable by default, meaning a cache may store a response with that code even without explicit Cache-Control or Expires headers. The cacheable codes are: 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, and 501.1 These defaults matter because they determine how intermediaries (browser caches, reverse proxies, CDNs) handle responses without any explicit caching instructions from your server.

The 404 and 410 trap

404 and 410 are on this list, which often surprises developers who expect error responses to be uncacheable. A cached 404 can block a client from reaching a resource you create later at the same URL. Add Cache-Control: no-store to 404 and 410 responses for any URL that might be created in the future.

302 and 307 temporary redirects are not cacheable by default, which is consistent with their temporary semantics: the redirect target may change.2 500, 502, 503, and 504 are also not cacheable by default: error responses should not be served from cache because the server may recover at any time.

Cache-Control directives with status codes

Cache-Control directives override the default cacheability defined by RFC 9110 for any status code, giving you precise control over which intermediaries cache your responses and for how long. Cache-Control: no-store prevents any cache from storing the response. Cache-Control: no-cache allows the cache to store the response but requires revalidation before serving it. Cache-Control: max-age=N allows the cache to serve the stored response for N seconds without revalidating.3

Choosing between no-cache and max-age

The interaction between Cache-Control and status codes requires care: setting max-age=86400 on a 404 response causes caches to serve the "not found" response for 24 hours, blocking legitimate requests to a URL you recreate during that window. Setting no-store on a 200 response for a high-traffic public asset wastes bandwidth by forcing every request to the origin.

RFC 9110 defines which HTTP status codes are cacheable by default: 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, and 501. Define a Cache-Control strategy for each status code your API can return, not just for successful responses. Audit your error responses (4xx and 5xx) for unintended cacheability, and audit your responses that include user-specific or sensitive data for unintended public caching. A single misconfigured Cache-Control header on a high-traffic endpoint can cause stale content to be served to thousands of users or force unnecessary origin load that degrades performance for everyone.

The 304 conditional request flow

The 304 Not Modified response is the mechanism for cache revalidation: the cache uses it to verify that a stored response is still fresh without re-downloading the full body.4 When a cache stores a response with an ETag header, subsequent requests to the same URL include If-None-Match: "etag-value" in the request headers. The server compares the current ETag with the stored one and returns 304 (no body, headers updated) if the resource has not changed, or 200 (new body, new ETag) if it has.4

Implementing ETag generation in your application is the key prerequisite for 304 responses to work: without it, the server cannot confirm whether the cached response is still valid and must return 200 on every request. Strong ETags based on content hashes change whenever the resource body changes, while weak ETags based on version identifiers allow semantically equivalent updates to skip revalidation.

The Vary response header defines which request headers the cache must include in the cache key. Vary: Accept-Encoding ensures separate cached copies for compressed and uncompressed responses. Without the correct Vary header, caches may serve a compressed response to a client that does not support compression, or serve a cached response built for one authenticated user to a different authenticated user.5

CDN-specific cache directives and their interaction with Cache-Control

Standard Cache-Control headers apply to all caching intermediaries: browsers, reverse proxies, and CDNs. CDN-specific cache directives allow you to set different caching rules for the CDN layer without affecting the browser cache. Cloudflare uses CDN-Cache-Control to set CDN-only caching rules that Cloudflare respects and browsers ignore.6 Fastly uses Surrogate-Control, which Fastly strips before forwarding the response to the browser. This separation allows responses that browsers should not cache (personal account data with Cache-Control: private) to be cached at the CDN edge for performance without privacy implications.

Configuring CDN-specific directives enables different browser and edge cache durations. A product page might set Cache-Control: public, max-age=60 (60-second browser cache) alongside Surrogate-Control: max-age=3600 (one-hour Fastly cache). Fastly serves the cached version for one hour from the edge while browsers revalidate every 60 seconds. This hybrid strategy improves origin offload without serving stale browser-cached content for extended periods.

Cache invalidation via surrogate keys

Fastly and Cloudflare both support tagged cache invalidation through surrogate keys. Adding a Surrogate-Key: product-123 category-electronics header to a response tags that cached response with both keys. When product 123's data changes, send a purge request to the CDN targeting the product-123 key, and Cloudflare or Fastly invalidates all cached responses bearing that key immediately, across all edge locations.6 This allows precise cache invalidation without purging unrelated cached responses that happen to share the same cache path.

When to use this

Use this guide when designing the caching strategy for an API or website. Reference it to confirm which status codes are cacheable by default, to set the correct Cache-Control directives for each response type, and to implement 304-based cache revalidation.

Examples

GET /api/products — high-traffic read endpoint with data that changes hourly

Return 200 with Cache-Control: max-age=3600, must-revalidate and an ETag. Caches serve the response for up to one hour. After expiry, the conditional request returns 304 if the product data has not changed, saving a full re-download.

DELETE /api/products/123 — product removed, URL will not be recreated

Return 410 Gone with Cache-Control: max-age=86400. Caches serve the 410 for 24 hours, reducing server load from repeated requests to the deleted URL. Use 410 rather than 404 so search engines deindex the URL faster.

POST /api/orders — order creation endpoint

Return 201 Created with Cache-Control: no-store. POST responses should not be cached: each creation is a distinct operation with a new resource URL. The Location header points to the cacheable resource at its own URL.

Sources
  1. 1.

    Roy Fielding, Mark Nottingham, and Julian Reschke, "HTTP Semantics," RFC 9110, IETF, June 2022. https://www.rfc-editor.org/rfc/rfc9110

  2. 2.

    Stack Overflow, "Which HTTP status codes are cacheable?," stackoverflow.com, accessed June 2026. https://stackoverflow.com/questions/39398653/which-http-status-codes-are-cacheable

  3. 3.

    Mozilla Developer Network, "Cache-Control," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control

  4. 4.

    Roy Fielding, Mark Nottingham, and Julian Reschke, "HTTP Caching," RFC 9111, IETF, June 2022. https://datatracker.ietf.org/doc/html/rfc9111

  5. 5.

    Mozilla Developer Network, "Vary," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary

  6. 6.

    Cloudflare, "CDN-Cache-Control," developers.cloudflare.com, accessed June 2026. https://developers.cloudflare.com/cache/concepts/cdn-cache-control/

FAQ