304 Not Modified
The cached copy the client already holds is still current, so the server sent no body. This is what makes conditional requests cheap.
At a glance
- Status code
- 304 Not Modified
- Class
- 3xx, redirection, further action is needed to complete the request
- Defined in
- RFC 9110
- Cacheable by default
- yes
- Response body
- None. A body is forbidden.
In detail
The client sent If-None-Match with an ETag, or If-Modified-Since with a date. The server compared, found no change, and answered with headers only. The client reuses what it has.
Emit it whenever a validator matches. A server that always returns 200 with a full body wastes bandwidth on every revalidation, even for content that never changes.
If a client re-downloads unchanged assets, check that the server sends ETag or Last-Modified in the first place. There is nothing to revalidate against without one.
Examples
HTTP/1.1 304 Not Modified
ETag: "33a64df5"
Cache-Control: max-age=0, must-revalidateThings that catch people out
- A 304 must not carry a body. Some frameworks serialise one anyway and the client hangs waiting for bytes the Content-Length promised.
- Weak ETags (prefixed W/) compare only semantic equivalence and cannot be used for range requests.
- If the resource is gzip encoded, the ETag must differ per encoding, or a client will be handed a compressed body it did not ask for.
Try it: HTTP Request Builder
Build a request with any method, headers and body, send it, and read the status line the server returns.
HTTP Request Builder
LOCAL · Browser-OnlyBuild and test HTTP requests with custom headers and body
Authentication
Headers
Generate Code
curl -X GET 'https://api.example.com/endpoint' \
-H 'Content-Type: application/json'Showing a sample URL. Enter your endpoint above to update the snippet.
Related HTTP status codes
All http status codes →200 OK
The request succeeded. What the body contains depends on the method: a GET returns the resource, a POST returns the result of the action.
412 Precondition Failed
A conditional header on the request, such as If-Match or If-Unmodified-Since, evaluated to false, so the server did not perform the action.
206 Partial Content
The server is returning part of the resource because the request carried a Range header. This is what makes resumable downloads and video seeking work.
305 Use Proxy
Deprecated. It once told the client to repeat the request through the proxy named in Location, which turned out to be a security problem.
307 Temporary Redirect
Same as 302 but with a guarantee: the client must repeat the request with the original method and body, so a POST stays a POST.
308 Permanent Redirect
A permanent redirect that preserves the request method and body. This is 301 without the historical POST to GET rewrite.
Tools for this
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL