If-Unmodified-Since
The HTTP If-Unmodified-Since request header guards state-changing operations against concurrent modifications by making the request conditional on the target resource remaining unchanged after a specified date.
Usage
Clients include If-Unmodified-Since to guard against overwriting changes made by others. The most common scenario involves an HTTP PUT or DELETE request where the client needs certainty the resource remains in the state observed earlier. If another client modified the resource after the date in the header, the server rejects the request with a 412 Precondition Failed response.
This addresses the lost update problem. Two clients fetch the same resource, both make edits, and both send updates. Without a precondition, the second update silently overwrites the first. Adding If-Unmodified-Since to the second request ensures the server detects the conflict.
The header value uses the HTTP date format. The server compares this date against the Last-Modified timestamp of the resource. When the resource modification date is equal to or earlier than the value in If-Unmodified-Since, the condition passes and the server continues processing.
For stronger consistency guarantees, prefer If-Match with an ETag value. ETags provide byte-level precision, while date-based conditions have a resolution of one second.
Values
HTTP-date
The value follows the IMF-fixdate format. The date represents the latest acceptable modification time for the resource.
If-Unmodified-Since: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
- day-name: abbreviated weekday (Mon, Tue, Wed, Thu, Fri, Sat, Sun)
- day: two-digit day of the month
- month: abbreviated month (Jan, Feb, Mar, etc.)
- year: four-digit year
- hour:minute:second: time in 24-hour format
- GMT: all HTTP dates use Greenwich Mean Time
Example
A client fetched a document on February 15, 2025, and now sends an update. The If-Unmodified-Since value matches the Last-Modified date received in the original response. If the document changed after this timestamp, the server responds with 412 Precondition Failed.
PUT /docs/report.json HTTP/1.1
Host: api.example.re
Content-Type: application/json
If-Unmodified-Since: Sat, 15 Feb 2025 10:30:00 GMT
When paired with a Range request for partial uploads, If-Unmodified-Since ensures the base resource has not changed between chunks.
PUT /files/dataset.csv HTTP/1.1
Host: api.example.re
If-Unmodified-Since: Fri, 14 Feb 2025 08:00:00 GMT
Content-Range: bytes 0-1023/4096
The one-second window
If-Unmodified-Since guards writes with a timestamp, and HTTP dates resolve to whole seconds. Two writes landing inside the same clock second carry the same Last-Modified value, so the guard passes and the second write overwrites the first without any precondition failing. The lost update the header exists to prevent slips through exactly where updates cluster.
If-Match with an entity tag closes the window, which is why the specification treats the tag comparison as authoritative: a server receiving both headers ignores If-Unmodified-Since entirely. The date form earns its place only where ETag generation is unavailable.
The second legitimate use pairs the header with range requests, resuming an interrupted download only while the file is unchanged. If-Range handles the same case in one request and is the better fit where the goal is parts-or-full rather than parts-or-412.
A 412 answer deserves care on retries. The correct response refetches the current state, reapplies the change, and resubmits with the fresh timestamp, since repeating the original request fails identically forever.
See also
- RFC 9110: HTTP Semantics
- Last-Modified
- If-Modified-Since
- If-Match
- Conditional-Requests
- 412
- HTTP headers