304

HTTP 304 Not Modified

3xx Redirection

3xx Redirection RFC 7232, Section 4.1

What is HTTP 304 Not Modified?

The 304 (Not Modified) status code indicates that a conditional GET request has been received and would have resulted in a 200 response if the condition was not true. The response has no body — the client should use its cached copy. This is the foundation of HTTP caching, allowing browsers to validate cached resources without re-downloading them.

Common Use Cases

  • Browser cache validation with ETag headers
  • Cache validation with Last-Modified headers
  • Reducing bandwidth for frequently accessed resources

Usage Example

When a browser requests a stylesheet it has cached, it includes the If-None-Match header with the ETag from the previous response. If the file has not changed, the server returns 304 Not Modified with no body, and the browser uses its cached copy. This significantly improves page load performance for repeat visits.

// Laravel - ETag-based cache validation
return response()
    ->file($path)
    ->setEtag(md5_file($path))
    ->setLastModified(new \DateTime('@' . filemtime($path)));
// Laravel automatically handles 304 responses

Common Mistakes

⚠️

Mistake: Sending a body with 304 Not Modified

Fix: A 304 response must never contain a message body. The client already has a valid cached copy. Sending a body wastes bandwidth and may confuse HTTP clients.

⚠️

Mistake: Returning 304 for non-cacheable resources

Fix: Only return 304 for requests that included conditional headers (If-Modified-Since or If-None-Match). If the client did not send validation headers, serve the resource with 200 OK.

⚠️

Mistake: Forgetting to include the same cache headers on 304 as the original 200

Fix: The 304 response should include the same ETag, Cache-Control, and Last-Modified headers as the original 200 response so the client can update its cache metadata.

Last updated: 21 Jun 2026