304 Not Modified answers a conditional GET or HEAD request, one that carries If-None-Match or If-Modified-Since, when the condition shows that the client's stored copy is still current. Instead of sending the resource again, the server answers 304 and the client uses its cached copy. This saves bandwidth and time.
A 304 never has a body; it ends with the empty line after the headers. The server must send those of the headers Cache-Control, Content-Location, Date, ETag, Expires and Vary that a 200 would have contained, so caches can update the stored response.
Although 304 is in the 3xx range, it is not a redirect. There is no Location, and the client stays on the same URL. A client that receives 304 without having sent a conditional request is talking to a broken server.
Example response
HTTP/1.1 304 Not Modified
Date: Fri, 06 Nov 2026 10:15:32 GMT
ETag: "5f2b-1a3c"
Last-Modified: Wed, 28 Oct 2026 08:02:11 GMT
Cache-Control: public, max-age=600
Vary: Accept-Encoding SEO and redirect checking
304 helps crawling. Google's crawlers support conditional requests, and a 304 tells Googlebot that the content has not changed since the last crawl. That saves crawl capacity and server load while the page keeps its place in the index, so reliable ETag or Last-Modified headers are worth having, especially on large sites.
TrueURL does not send conditional headers by default, so you will see 200 rather than 304. To test revalidation, add an If-None-Match header with the page's ETag under Custom Request Headers.
Common causes and use cases
- A browser revalidates a cached page, image or script with
If-None-Match, and theETagstill matches. - A crawler or feed reader fetches again with
If-Modified-Since, and nothing has changed. - Visitors see stale content after a deploy because the server keeps answering 304: its validators did not change, for example an
ETagbuilt from file size and modification time that the deploy preserved. Make sure validators change whenever the content does.