HTTP Status Code 412 = “Precondition Failed”
The server rejected the request because one or more conditions specified in the request headers were not met.
Common causes
412 usually occurs with conditional headers like:
If-MatchIf-None-MatchIf-Unmodified-SinceIf-Modified-Since
These headers are commonly used for:
- caching,
- concurrency control,
- preventing overwrite conflicts. Example with ETag
Client request
http id=”q8m2we”
PUT /document/1 HTTP/1.1
If-Match: “abc123”
Server resource has changed
http id=”v5k7ra”
ETag: “xyz999”
Response
http id=”n3p1xd”
HTTP/1.1 412 Precondition Failed
The update is rejected because the file/version changed.
Common real-world scenarios
- Collaborative editing systems
- APIs with version control
- Browser caching
- Cloud storage uploads
- REST APIs using ETags Why it exists
412 prevents:
- accidental overwrites,
- stale updates,
- cache inconsistencies,
- race conditions. Fixes
For users
- Refresh the page/data
- Retry the action
- Re-upload the latest version
For developers
1. Refresh ETag/version before update
Get latest resource first:
http id=”u9w4kc”
GET /document/1
Then retry update using latest ETag.
2. Remove incorrect conditional headers
Example:
http id=”g7q2mv”
If-Match: old-etag
3. Node.js example
js id=”r4k8zn”
if (req.headers[‘if-match’] !== currentEtag) {
return res.status(412).send(‘Precondition Failed’);
}
4. Laravel example
php id=”t6p3xe”
return response(‘Precondition Failed’, 412);
Difference between 409 and 412
| Code | Meaning |
| — | – |
| 409 | General conflict |
| 412 | Conditional header failed |
Common headers involved
| Header | Purpose |
| | |
| ETag | Resource version identifier |
| If-Match | Update only if version matches |
| If-None-Match | Cache validation |
| If-Unmodified-Since | Prevent stale updates |
Related HTTP status codes
| Code | Meaning |
| — | |
| 304 | Not Modified |
| 409 | Conflict |
| 412 | Precondition Failed |
| 428 | Precondition Required |