304 Not Modified

The HTTP 304 Not Modified redirection response status code indicates that there is no need to retransmit the requested resources.

This response code is sent when the request is a conditional GET or HEAD request with an If-None-Match or an If-Modified-Since header and the condition evaluates to 'false'. It confirms that the resource cached by the client is still valid and that the server would have sent a 200 OK response with the resource if the condition evaluated to 'true'.

The response must not contain a body and must include the headers that would have been sent in an equivalent 200 response, such as:

Note: Many developer tools' network panels of browsers create extraneous requests leading to 304 responses, so that access to the local cache is visible to developers.

Status

http
304 Not Modified

Examples

304 response to conditional requests

The examples below show GET requests made using curl with conditional request headers. The --http1.1 flag is used to force the HTTP/1.1 protocol for readability.

The first request uses an If-Modified-Since condition with a future date of 21st November 2050. This must evaluate to false, because the resource can't have been updated after a time that hasn't happened yet:

bash
curl --http1.1 -I --header 'If-Modified-Since: Tue, 21 Nov 2050 08:00:00 GMT' \
 https://developer.mozilla.org/en-US/

This will result in the following HTTP request:

http
GET /en-US/ HTTP/1.1
Host: developer.mozilla.org
User-Agent: curl/8.7.1
Accept: */*
If-Modified-Since: Tue, 21 Nov 2050 08:00:00 GMT

The response would be 200 OK with the current version of the resource if the resource had been updated after the timestamp in the If-Modified-Since header. Instead, we get a 304 response that includes ETag, Age and Expires headers, telling us our cached version of the resource is still current:

http
HTTP/1.1 304 Not Modified
Date: Wed, 28 Aug 2024 09:52:35 GMT
Expires: Wed, 28 Aug 2024 10:01:53 GMT
Age: 3279
ETag: "b20a0973b226eeea30362acb81f9e0b3"
Cache-Control: public, max-age=3600
Vary: Accept-Encoding
X-cache: hit
Alt-Svc: clear

Now run another curl command using the etag value from the previous response with the If-None-Match condition (since this etag is the current version of the resource on the server we expect to receive a 304 Not Modified response):

bash
curl --http1.1 -I --header 'If-None-Match: "b20a0973b226eeea30362acb81f9e0b3"' \
 https://developer.mozilla.org/en-US/

This will result in the following HTTP request:

http
GET /en-US/ HTTP/1.1
Host: developer.mozilla.org
User-Agent: curl/8.7.1
Accept: */*
If-None-Match: "b20a0973b226eeea30362acb81f9e0b3"

Because the etag value matches at the time of the request, the entity tag fails the condition, and a 304 response is returned:

http
HTTP/1.1 304 Not Modified
Date: Wed, 28 Aug 2024 10:36:35 GMT
Expires: Wed, 28 Aug 2024 11:02:17 GMT
Age: 662
ETag: "b20a0973b226eeea30362acb81f9e0b3"
Cache-Control: public, max-age=3600
Vary: Accept-Encoding
X-cache: hit
Alt-Svc: clear

Specifications

Specification
HTTP Semantics
# status.304

Compatibility notes

Browser behavior differs if this response erroneously includes a body on persistent connections. See 204 No Content for more details.

See also