If-Modified-Since: date based conditional requests
If-Modified-Since asks the server to send the body only if the resource changed after the given date. If it did not, the answer is 304 Not Modified.
At a glance
- Direction
- Request only. The date comes from a Last-Modified header the client received earlier.
- Defined in
- RFC 9110
- When absent
- The server returns the full body, or relies on If-None-Match if that was sent instead.
- Applies to
- GET and HEAD. Servers ignore it on other methods.
- Ignored when
- If-None-Match is present in the same request
- Result
- 304 Not Modified with no body, or 200 with the full representation
- Resolution
- One second, so same-second edits go undetected
In detail
The client echoes a date it previously received in Last-Modified. The server compares it with its current modification time and, if nothing is newer, replies 304 with headers only. It is the oldest revalidation mechanism in HTTP and the one most likely to be understood by an ancient client or an intermediary that ignores entity tags.
It is defined only for GET and HEAD. A conditional write is a different problem with a different answer, and the header for that is If-Unmodified-Since, which fails with 412 rather than succeeding with 304. Servers are required to ignore this header on other methods rather than guessing what was meant.
Servers must also ignore it when the request carries If-None-Match, and must ignore an unparseable date rather than treating it as the beginning of time. Both rules exist so that a malformed or contradictory conditional request degrades into a normal full response rather than into a wrong 304.
The one second resolution is the practical limit. A resource that changes several times a second cannot be revalidated correctly with dates alone, and the client will be told 304 while holding a version that is already superseded. That is the case an ETag exists for.
Examples
GET /assets/logo.svg HTTP/1.1
If-Modified-Since: Tue, 15 Nov 2022 08:12:31 GMT
HTTP/1.1 304 Not Modifiedcurl -sI -H 'If-Modified-Since: Tue, 15 Nov 2022 08:12:31 GMT' https://example.com/assets/logo.svgA 200 here means either the file changed or the server is not honouring date conditionals at all.
Things that catch people out
- Sending a date the server never issued is legal but pointless: a date in the future usually causes a 304 for content that has in fact changed.
- The date format must be the GMT form used by Last-Modified. An ISO 8601 timestamp is not a valid HTTP date and is ignored.
- Static file handlers often compare against the file system timestamp, so a redeploy that rewrites files without changing them invalidates every client's copy.
Try it: HTTP Headers Checker
Check a live URL or paste headers you already have. It grades six security headers from A+ to F and lists every other header the response returned.
HTTP Headers Checker
LOCAL · Browser-OnlyView HTTP response headers for any URL
Enter any website URL to fetch and analyze its HTTP response headers. We'll automatically add https:// if needed.
Why Check Security Headers?
Security headers protect your website against common attacks like XSS, clickjacking, and MIME sniffing. They're set by your web server and cost nothing to implement. Missing security headers are one of the most common findings in security audits.
Related HTTP headers
All http headers →Last-Modified: timestamps as a weak validator
The exact date format Last-Modified requires, why one second resolution makes it a weak validator, and how caches use it to guess freshness.
If-None-Match: asking whether anything changed
How If-None-Match produces a 304, why it uses weak comparison, how it overrides If-Modified-Since, and its second job preventing duplicate creates.
If-Unmodified-Since: a date based conditional write
How If-Unmodified-Since guards a write with a timestamp instead of an entity tag, when servers ignore it, and why an ETag is the stronger guarantee.
ETag: version identifiers for conditional requests
How an ETag is compared, when to use a weak tag, how it drives 304 responses and 412 conflicts, and why compression changes the tag a server sends.
If-Match: safe updates and the lost update problem
How If-Match turns a PUT or PATCH into a conditional write, why it uses strong comparison, and how 412 Precondition Failed prevents silent overwrites.
Pragma: a deprecated header still copied everywhere
What Pragma: no-cache ever did, why it only applied to requests, why it is deprecated in RFC 9111, and whether there is any reason to keep sending it.
Tools for this
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body