A 304 Not Modified response means the server confirmed a cached copy is still current, so it sends headers only and the client reuses its stored file. This guide covers the ETag and Last-Modified headers behind it, how Google treats 304s, and 6 checks to fix stale-content problems.
In This Article
Share On:
You open a site you visited yesterday and it loads almost instantly. Part of that speed comes from the 304 status code, the HTTP response a server sends when your browser already holds a valid copy of a file.
This guide explains what HTTP 304 Not Modified means, the headers behind it, how Googlebot treats it and how to fix stale-content problems.
What Does the 304 Status Code Mean?
A 304 status code (304 Not Modified) means the server checked your browser’s cached copy, found it’s still current, and replied with headers only, no body. The browser then loads the file from its cache. RFC 9110 defines it as the answer to a conditional GET or HEAD request whose condition evaluated to false.
In plain terms, status 304 means “nothing changed, use what you have.” Otherwise, the server would have sent a 200 OK with the full resource (MDN’s 304 reference).
Is a 304 code an error or a redirect?
It’s not an error, and it doesn’t send anyone to a new URL. RFC 9110 lists 304 in the 3xx redirection class as “redirection to a previously stored result.” So a 304 error code usually means caching is working as designed.
304 vs 200, 301, 302 and 404: How the Status Codes Compare
A 200 sends the full resource, a 301 or 302 points to another URL, a 404 says nothing was found, and a 304 tells the client to reuse the copy it already stores. Only a 304 response code needs a cached copy first.
304 status code vs other HTTP status codes (RFC 9110, Google Search Central)
Status code
Meaning
What the client receives
How Google Search treats it
200 OK
Request succeeded
Full resource in the body
Passes the content to the indexing pipeline
301 Moved Permanently
New permanent URL
A Location header with the new URL
Strong signal to process the redirect target
302 Found
Temporarily at a different URL
A Location header with the temporary URL
Weak signal to process the redirect target
304 Not Modified
Cached copy is still valid
Headers only, no body
Content is the same as the last crawl; no other effect on indexing
How Does a 304 Not Modified Response Work? Step by Step
A 304 happens in 3 steps: the server hands out a validator with the first response, the browser sends it back later, and the server compares it with the current file. If they match, the answer is 304.
Step 1: First visit, the server sends validators
No cache exists yet, so the server replies with the full content plus caching headers:
HTTP/1.1 200 OK
Last-Modified: Tue, 03 Mar 2026 10:00:00 GMT
ETag: "abc123"
Cache-Control: max-age=86400
With max-age=86400 the stored copy stays fresh for 24 hours and is reused without contacting the server (MDN’s HTTP caching guide).
Step 2: Return visit, the browser sends a conditional request
Once the copy goes stale, the browser asks again with the validators it saved:
GET /page.html HTTP/1.1
If-None-Match: "abc123"
If-Modified-Since: Tue, 03 Mar 2026 10:00:00 GMT
Step 3: The server returns 304 or 200
If the ETag matches, the server replies 304 with no body; if the file changed, it sends 200 OK. Per RFC 9110 section 15.4.5, a 304 must still include headers such as Date, ETag and Cache-Control that a 200 would have sent:
HTTP/1.1 304 Not Modified
Date: Wed, 04 Mar 2026 10:00:00 GMT
ETag: "abc123"
Cache-Control: max-age=86400
Headers that control a 304 response
Last-Modified (server to browser): date and time of the last change.
ETag (server to browser): an opaque tag for this version of the file.
If-Modified-Since (browser to server): send the file only if it changed after this date.
If-None-Match (browser to server): send the file only if its ETag no longer matches.
Cache-Control (server to browser): how long the copy stays fresh, or whether it must be revalidated first.
Prefer ETags for dynamic pages. Under RFC 9110 section 13.1.3, a server must ignore If-Modified-Since when If-None-Match is present, because the entity tag check is considered more accurate.
Watch: 304 Not Modified explained
4 Real-World 304 Examples: CSS Files, Blog Posts, APIs and CDNs
You’ll see 304 responses wherever a client revalidates something it already stores.
Example 1: CSS and JavaScript files
Your stylesheet hasn’t changed in a week, so returning visitors with stale copies get a 304 and reuse the stored file. As an illustration, skipping a 150KB file for 10,000 returning visitors a day avoids about 1.5GB of transfer daily (headers still travel).
Example 2: A blog post that hasn’t been updated
A reader revisits last month’s post. The HTML returns 304, so the page renders from cache faster than on the first visit. Googlebot can get the same 304 when it recrawls the URL.
Example 3: API responses
A 304 status code in an API works the same way. A client sends the stored ETag in If-None-Match, and the API answers 304 when the data hasn’t changed. RFC 9110 calls this updating cached information “with a minimum amount of transaction overhead.”
Example 4: CDN edge caches
CDNs revalidate too. Cloudflare’s ETag documentation says matching ETag values produce a 304, though Cloudflare can weaken or remove strong ETags depending on compression and some settings.
Does the 304 Status Code Affect SEO?
Not directly. Google says a 304 tells its systems the content is the same as at the last crawl; the indexing pipeline may recalculate signals, but the code otherwise has no effect on indexing. The benefits are indirect.
How Googlebot handles a 304
Google’s crawlers support ETag with If-None-Match and Last-Modified with If-Modified-Since. Google recommends ETag because it avoids date formatting issues, and uses the ETag when both headers are present.
Crawl budget on large sites
Google’s crawl budget guide advises supporting 304 so Google can reuse its cached version, saving your bandwidth and server resources. It targets sites with 1 million+ unique pages that change weekly, or 10,000+ pages that change daily.
A 304 isn’t a fault. Trouble starts when a server keeps answering 304 after content changes, so people see stale pages, or answers 200 every time, so nothing is revalidated. Work through these 6 checks.
Check your server configuration
Confirm ETag and Last-Modified change whenever content changes. If an updated page still returns a 304 status code, a stale ETag is the first suspect. Avoid no-store on pages you want crawled efficiently: under RFC 9111 it bans storing the response, while no-cache still allows 304 revalidation.
Inspect the browser cache
A normal reload revalidates with If-None-Match, while a force reload sends Cache-Control: no-cache, per MDN’s caching guide. If a force reload shows new content, the old copy was simply cached.
Verify CDN settings
Compare the ETag your origin sends with the one visitors get. On Cloudflare, compression mismatches, Email Obfuscation and Automatic HTTPS Rewrites can weaken or strip ETags.
Test different devices and browsers
Compare a private window, a second browser and a phone. If only 1 device shows old content, clear that cache. If all do, look at the server or CDN.
Use developer tools and logs
In Chrome DevTools, check each request’s status and Response Headers in the Network tab. Tick Disable cache to see a first visit. MDN notes network panels can trigger extra 304s, so confirm patterns in server logs during your technical SEO audit.
Version files that change
Put a version number or hash in CSS and JavaScript file names and serve them with a long max-age. MDN calls this cache busting: a changed file gets a new URL, so nobody is stuck with an old copy.
304 Status Code FAQs
Is a 304 Not Modified response good or bad?
A 304 is good. It means caching works: the server confirmed the stored copy is current and skipped resending the body, which saves bandwidth and speeds up repeat visits. It’s only a problem when the server keeps returning 304 after content changes, usually because the ETag didn’t update.
Does a 304 status code affect SEO?
Not directly. Google’s documentation says a 304 tells its systems the content is the same as at the last crawl. The indexing pipeline may recalculate signals, but otherwise the code has no effect on indexing. Indirectly, 304 support saves server resources during crawls.
What is the difference between a 304 and a 200 from cache?
A 304 needs a round trip: the browser asks whether its copy is still valid and the server answers with headers only. A 200 from cache involves no request at all, because the stored response is still fresh under its Cache-Control max-age, so the browser reuses it without contacting the server.
Why do I see status 304 in the browser network tab?
Your browser already had those files, revalidated them, and the server confirmed they hadn’t changed. That’s normal on repeat visits. MDN notes developer tools can create extra requests that lead to 304 responses, so tick Disable cache in Chrome DevTools to see a first-time visit.
Why does Google Search Console show 304 responses?
The Crawl Stats report, under Settings, groups crawl requests by response. Google describes Not modified (304) as a page that hasn’t changed since the last crawl request, so it’s normal for stable pages. If an updated page still returns 304, check that your ETag or Last-Modified value changes with the content.
How do I make my server return 304 responses?
You can’t force a 304 directly. Configure your server or CDN to send ETag or Last-Modified headers, plus Cache-Control. Browsers and crawlers then send conditional requests with If-None-Match or If-Modified-Since, and the server answers 304 automatically whenever the resource hasn’t changed since their last visit.
Your Next Move: Get Your Caching Headers Right
A 304 is a sign of healthy caching, not an error. Make sure validators update when content changes, and that repeat visitors and crawlers get 304s for everything else.
Our technical SEO services team reviews cache headers, CDN settings and Core Web Vitals together. Contact us to request an audit.
For Curious Minds
These headers provide a unique signature for a resource, allowing the server to check if the browser's cached version is current without re-sending the file. This validation process is the foundation of the 304 Not Modified response, which conserves bandwidth and drastically shortens load times for users who have visited your site before. The server sends these validator headers with the initial 200 OK response, preparing the browser for future checks.
The conditional validation works through a request-response cycle:
Last-Modified: A timestamp indicating the last alteration. The browser sends this back in an `If-Modified-Since` header.
ETag (Entity Tag): A unique identifier, often a content hash, that is more accurate than a timestamp. The browser sends this back in an `If-None-Match` header.
Implementing this strategy correctly is vital for efficient content delivery. By enabling the server to respond with a lightweight 304 status, you avoid unnecessary data transfer, which directly improves the user experience. You can find more details on configuring these headers in the complete guide.
A 304 status code instructs the browser to use a local, cached copy of a resource, whereas 301 and 302 redirects direct the browser to a completely new URL. The 'redirection' in a 304 is to an existing local asset, not a different network location. This distinction is crucial: a 304 prevents a network download, while 301s and 302s initiate one.
Here is how their purposes diverge:
304 Not Modified: This tells the client, 'The resource you requested at this URL has not changed since you last saw it. Use the version you already have.' It includes no body.
301 Moved Permanently: This tells the client, 'The resource you requested has a new, permanent address. Go there instead and update your bookmarks.'
302 Found: This tells the client, 'The resource is temporarily at a different address. Go there for now, but continue using the original URL for future requests.'
This 'redirection to cache' is a powerful performance feature. Understanding this difference helps you diagnose website behavior correctly. The full article provides more context on how each status code class impacts client and server interactions.
Loading from a fresh cache via `max-age` is faster because it involves no network request, while a 304 response still requires a quick round-trip to the server to validate the resource. The `Cache-Control: max-age` directive tells the browser it can use its cached copy for a specified duration, like `max-age=86400` for 24 hours, without asking the server. A 304 occurs only after this period expires and the browser must re-validate its stale copy.
Weigh the two caching strategies based on your content's volatility. The ideal approach often involves using both for a layered defense against slow load times. For static assets that rarely change, a long `max-age` is superior. For resources that might update, a shorter `max-age` followed by 304 validation ensures users get fresh content without forcing a full download every time. The full post explores how to balance these two methods for optimal performance.
Googlebot treats a 304 Not Modified as a positive signal that content is stable, which helps conserve your crawl budget. When Googlebot receives a 304, it understands the page has not changed since the last crawl and moves on without re-processing the content. In contrast, a 500 Internal Server Error signals a server problem that wastes crawl budget and, if persistent, can lead to the URL being dropped from the index.
A well-tuned server that correctly serves 304s tells Google Search Central that your site is efficient. This allows its crawlers to discover new or updated content on your site more quickly rather than re-downloading unchanged resources. Properly managing 304 responses is a key technical SEO practice for large websites. This preserves crawl equity for pages that truly need attention. You can learn more about the specific SEO implications of different HTTP codes in our detailed guide.
The process for a 304 response is a clear, three-part conversation between the client and server to confirm if a cached file is still valid. It begins with the server providing validation tokens on the first visit, which the browser then uses to ask for confirmation later. This avoids re-downloading data unnecessarily.
The exchange happens in this order:
First Visit: The server responds with 200 OK, delivering the resource along with `ETag: "abc123"` and `Last-Modified` headers.
Return Visit: After the local cache becomes stale, the browser requests the same resource but includes conditional headers, such as `If-None-Match: "abc123"`.
Server Validation: The server compares the received `ETag` with the current file's ETag. If they match, it replies with 304 Not Modified and an empty body.
This handshake is fundamental to an efficient web experience, as explained in resources like the MDN Web Docs. Mastering this flow is essential for any developer looking to build fast, responsive sites. The full article breaks down each header's role in greater detail.
To properly trigger 304 responses, you must configure your web server to generate and honor caching headers for your assets. This setup tells browsers how to cache files and how to ask if they are still fresh later. A correct configuration reduces server processing time and bandwidth usage significantly.
Follow these implementation steps:
Enable ETags: Ensure your server (e.g., Apache, Nginx) is configured to generate an `ETag` header for static files like images, CSS, and JavaScript.
Set Cache-Control: Add a `Cache-Control` header with a `max-age` value, such as `max-age=86400`, to define how long the browser should use its local copy before re-validating.
Verify Conditional Logic: Confirm your server logic correctly checks for `If-None-Match` and `If-Modified-Since` headers in incoming requests and returns a 304 status when validators match.
This initial setup creates a more scalable and cost-effective infrastructure. The effort pays off by minimizing redundant work for your server. Our complete guide offers specific configuration examples for popular server software.
A site that unnecessarily serves 200 OK responses for unchanged assets will have slower load times for returning visitors, which can negatively affect its Core Web Vitals scores. Since metrics like Largest Contentful Paint (LCP) are influenced by resource load speed, failing to use 304s can harm your SEO performance over time. Search engines favor sites that provide a fast, efficient user experience.
Failing to optimize caching is a missed opportunity that compounds over time. A site that properly leverages 304 responses not only feels faster to users but also signals technical proficiency to crawlers like Googlebot. This efficiency can lead to a better crawl rate and a stronger overall performance profile, which are positive factors for search rankings. Delve into the full article to understand how to align your caching strategy with modern SEO expectations.
Stale content issues frequently arise from incorrect `ETag` generation, especially in multi-server or load-balanced environments where ETags differ for the same file. Another common problem is a server ignoring the `If-None-Match` or `If-Modified-Since` headers sent by the browser. You can diagnose these issues effectively using your browser's built-in developer tools.
To troubleshoot, open the 'Network' tab in your browser's developer tools and follow these steps:
Inspect Headers: Check the response headers for the initial resource load to see if `ETag` and `Last-Modified` are present.
Monitor Revalidation: Refresh the page and inspect the next request for that same resource. Verify that the browser sends the appropriate `If-None-Match` or `If-Modified-Since` request headers.
Check the Response: Analyze the server's response. If it sends a 200 OK with the full file instead of a 304 Not Modified, your server's validation logic is likely misconfigured.
Systematic inspection is the key to resolving these frustrating caching puzzles. Our full guide provides deeper insights into fixing these specific problems.
A 304 response indicates that your caching system is working precisely as designed, confirming to the browser that its local copy is still valid. It is not an error but an efficiency confirmation. By sending only headers and no body, the server saves bandwidth and the client avoids a redundant download, leading to a faster experience for the user.
Even without a body, the 304 response provides critical information in its headers, as mandated by RFC 9110. It must include headers like `Date`, `ETag`, and `Cache-Control` that would have been present in a 200 OK response for the same resource. This header refresh allows the browser to update the metadata for the cached item, such as resetting its `max-age` timer. It is a lightweight handshake that maintains cache integrity. Discover more about what these updated headers mean for cache longevity in the full article.
A 304 Not Modified response tells Googlebot that the page content is the same as the last time it was crawled, making it a neutral and efficient signal. This has no negative effect on indexing; it simply confirms the existing index is still accurate. In contrast, a 404 Not Found response is a strong signal that the page no longer exists, which prompts Google to remove the URL from its search results to avoid sending users to a dead link.
Think of it in terms of instruction:
304 Not Modified: 'No news is good news. The content you have on file is still correct.'
404 Not Found: 'This content has been removed. You should delete your record of it.'
Your server's status codes are a direct line of communication with search engines. Consistently serving 304s for unchanged content shows Google Search Central your site is reliable, whereas frequent 404s can signal poor maintenance. Read the complete guide to see how other codes like 301 and 500 affect your site's SEO health.
The most probable cause is that your server is not correctly configured to process or respect conditional headers like `If-Modified-Since` and `If-None-Match`. This forces the server to send the full resource every time, wasting bandwidth. The issue often lies in the server software's configuration file or in custom application code that overrides default caching behaviors.
To troubleshoot this, focus on the server's validation logic. You can start by checking if the `Last-Modified` header is being sent correctly on the initial response. Then, use a tool like `curl` or browser developer tools to manually send a request with an `If-Modified-Since` header containing that exact timestamp. If the server still replies with a 200 OK instead of a 304 Not Modified, the validation logic is broken. Fixing this is a high-impact optimization for any website. Explore the full article for detailed examples on debugging and resolving these common caching issues.
The 304 Not Modified status code is exceptionally well-suited for optimizing API data transfer, not just static files. As applications fetch dynamic data, an API endpoint can use an `ETag` based on the hash of the JSON response. When the client requests that data again, it can include the `If-None-Match` header, allowing the server to send a 304 response if the underlying data has not changed.
This approach provides significant benefits for dynamic content:
Reduced Bandwidth: Prevents re-sending large JSON payloads that are identical to the client's cached version.
Lower Server Load: The server may only need to perform a quick check (e.g., on a timestamp or hash in a database) rather than re-building the entire API response from scratch.
Improved Client Performance: The application feels faster because it can instantly use its cached data upon receiving a 304 confirmation.
This method transforms caching from a static file concern into a core part of dynamic application architecture. The full guide touches on how these principles apply to a broader range of web resources.
Amol has helped catalyse business growth with his strategic & data-driven methodologies. With a decade of experience in the field of marketing, he has donned multiple hats, from channel optimization, data analytics and creative brand positioning to growth engineering and sales.