What HTTP 304 means
When a client revalidates a cached response with If-None-Match (ETag) or If-Modified-Since, the server returns 304 with no body if nothing changed. The client keeps using its cached copy, saving bandwidth. Seeing many 304s in DevTools is a good sign that caching works.
Using 304 correctly
-
If you always get 200 instead of 304, check that the server sends a stable
ETagorLast-Modified. Some load balancers generate different ETags on each server.
Retrying
Not applicable: this isn’t an error.
Example response
HTTP/1.1 304 Not Modified
Date: Wed, 21 Oct 2026 10:30:00 GMT
ETag: "33a64df5"
Cache-Control: max-age=0, must-revalidate
How to return 304
res.status(304).end();
from fastapi import Response
return Response(status_code=304)
w.WriteHeader(http.StatusNotModified)
Related status codes
- 200 OK : The request succeeded and the response contains the result.
- 412 Precondition Failed : A condition in the request headers, such as If-Match, was not met.
- 206 Partial Content : The server is returning only the byte range the client asked for.
Other 3xx status codes
300 Multiple Choices · 301 Moved Permanently · 302 Found · 303 See Other · 307 Temporary Redirect · 308 Permanent Redirect
See the full list of HTTP status codes.
Sources
Spotted a mistake? Email hello@devtoolsmith.com and we’ll fix it.
Frequently asked questions
What does HTTP 304 Not Modified mean?
HTTP 304 Not Modified tells the client its cached copy is still valid, so no body is sent. When a client revalidates a cached response with If-None-Match (ETag) or If-Modified-Since, the server returns 304 with no body if nothing changed. The client keeps using its cached copy, saving bandwidth. Seeing many 304s in DevTools is a good sign that caching works.