304 Not Modified
The cached copy the client already holds is still current, so the server sends no body.
Status
HTTP/1.1 304 Not Modified
Details
- Category: 3xx
- Status: Standard. Registered with IANA and defined by a current standards-track RFC.
- Specification: RFC 9110 §15.4.5, RFC 9111 §4.3.4: Caching behaviour on revalidation
- Cacheable: Cacheable by default
- Response body: Must not be sent
- Retry: Not applicable
304 answers a conditional request. The client sends If-None-Match with an ETag or If-Modified-Since with a date, and if nothing changed the server replies 304 with headers only. The client then serves its stored copy. This is the single largest bandwidth saving mechanism in everyday HTTP.
The response must not include a body, and it must carry the validators and cache headers that would have accompanied a 200 so the client can update its freshness bookkeeping.
Note: A 304 carries no body. The client is expected to serve the copy it already holds, so the response must repeat the validators and cache headers that came with the original 200.
Headers
- ETag: Should match the validator that made the request conditional.
- Cache-Control: Refreshes the stored freshness lifetime of the cached representation.
- Vary: Must be consistent with the original 200 or caches may serve the wrong variant.
Common causes
- A browser revalidated an expired cache entry and nothing had changed.
- A crawler sent If-Modified-Since and the page was untouched since the last visit.
Usage notes
For clients
- Serve the stored copy. Do not try to parse the empty body.
- If you want the full payload for a scrape, omit If-None-Match and If-Modified-Since, or send Cache-Control: no-cache.
For servers
- Emit stable ETags. Regenerating a different ETag for identical content defeats revalidation entirely.
- Include the same Vary header as on the 200, or shared caches will mismatch variants.
Examples
Revalidating a cached asset
A revalidation request carrying the ETag the client already holds:
HTTP request
GET /assets/app.css HTTP/1.1 Host: www.example.com If-None-Match: "9f2c31"
Nothing changed, so the server sends headers only and the client serves its stored copy:
HTTP response
HTTP/1.1 304 Not Modified ETag: "9f2c31" Cache-Control: public, max-age=86400
Notes for proxy users
Crawlers that store validators and send conditional requests get 304s instead of full pages, which cuts bandwidth and lowers the request footprint on the target site. That is worth doing even on unmetered proxy plans because it reduces the load pattern that triggers rate limiting.
Specifications
- RFC 9110 §15.4.5
- RFC 9111 §4.3.4: Caching behaviour on revalidation