304
Not Modified
3xx Redirection

What Does HTTP 304 Not Modified Mean?

HTTP 304 Not Modified is a response to a conditional request. It tells the client that the resource has not been modified since the last time it was fetched, so the cached version can be reused. The server sends only headers — no body — saving bandwidth and improving load times.

This status code is a cornerstone of HTTP caching. It works through two mechanisms:

Common Causes

How Conditional Requests Work

ETag-based flow

# First request - server provides ETag $ curl -I https://example.com/style.css HTTP/1.1 200 OK ETag: "abc123" Content-Type: text/css Content-Length: 45230 # Second request - browser sends If-None-Match $ curl -I -H 'If-None-Match: "abc123"' https://example.com/style.css HTTP/1.1 304 Not Modified ETag: "abc123" # No body sent - browser uses cached version

Last-Modified flow

# First request $ curl -I https://example.com/data.json HTTP/1.1 200 OK Last-Modified: Wed, 15 Jan 2025 10:00:00 GMT Content-Type: application/json # Second request - browser sends If-Modified-Since $ curl -I -H 'If-Modified-Since: Wed, 15 Jan 2025 10:00:00 GMT' \ https://example.com/data.json HTTP/1.1 304 Not Modified # Cached version is still current

Nginx ETag Configuration

# ETags are enabled by default in Nginx for static files # To explicitly control it: location /static/ { etag on; # Enable ETags (default) if_modified_since exact; # Exact timestamp matching expires 1h; # Cache for 1 hour, then revalidate } # To disable ETags (e.g., behind a load balancer where # different servers generate different ETags): location /api/ { etag off; add_header Cache-Control "no-cache"; }

Debugging 304 Issues

Frequently Asked Questions

What triggers a 304 Not Modified response?
A 304 is triggered when the browser sends a conditional request with If-None-Match (ETag) or If-Modified-Since (timestamp), and the server confirms the resource has not changed. The browser then uses its cached copy. This is automatic — browsers handle conditional requests transparently based on caching headers from previous responses.
Why am I getting 304 when content has changed?
This usually means ETags or Last-Modified timestamps are not updating when content changes. Common causes: deployment scripts that preserve file timestamps, weak ETags based on file size (if size did not change), or CDN caching stale ETags. Fix by ensuring your build pipeline generates new fingerprints, or add cache-busting query strings to asset URLs.
Is 304 Not Modified an error?
No. 304 is a success response that optimizes performance. It means your cache is working correctly. The server validated the cached resource and confirmed it is still current, saving the bandwidth of re-transmitting the full response body.

Related Status Codes

Related Tools