304 Not Modified (RFC 7232)
This is an educational reference page about HTTP 304 Not Modified. The page itself is served as 200 OK so it can be indexed as HTTP documentation.
Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match. In such case, there is no need to retransmit the resource since the client still has a previously-downloaded copy.
What it means
HTTP 304 Not Modified means the cached copy is still valid, so the server does not need to send the response body again.
Common causes
- A browser or CDN sends If-None-Match with an ETag from a previous response.
- A client sends If-Modified-Since with a Last-Modified timestamp.
- Static assets, API responses, or pages are being revalidated instead of downloaded again.
How to fix it
- Return 304 only when the cached representation still matches the current resource.
- Send strong or weak ETag values consistently for cacheable responses.
- Use Last-Modified when timestamp-based validation is accurate enough.
- Keep Cache-Control, ETag, Vary, and Last-Modified behavior consistent across the CDN and origin.
- Return 200 with a full body when the resource changed or validators do not match.
Example response
GET /app.css HTTP/1.1
If-None-Match: "abc123"
HTTP/1.1 304 Not Modified
ETag: "abc123"
Cache-Control: public, max-age=3600
Developer notes
304 is a successful cache validation response. It saves bandwidth and speeds up repeat visits, but incorrect validators can make clients keep stale content.
Questions
What does HTTP 304 mean?
HTTP 304 means the client can reuse its cached copy because the resource has not changed.
Is 304 an error?
No. 304 Not Modified is not an error. It is a normal cache validation response.
What headers cause a 304 response?
If-None-Match and If-Modified-Since commonly trigger 304 when they match the server's current ETag or Last-Modified value.
Should a 304 response include a body?
No. A 304 response does not include the full response body; the client uses its cached body instead.