412 Precondition Failed
This is an educational reference page about HTTP 412 Precondition Failed. The page itself is served as 200 OK so it can be indexed as HTTP documentation.
One or more conditions in the request header fields evaluated to false on the server.
Specification
Registered in the IANA HTTP Status Code Registry as Precondition Failed. Defined in RFC 9110, Section 15.5.13.
What it means
HTTP 412 Precondition Failed means the client sent a conditional request and the condition was false. The usual case is optimistic concurrency: the client sends If-Match with the ETag it last saw, and the server answers 412 because the resource has changed since then. The update is not applied.
When to use it
- Return 412 when If-Match does not match the current ETag on a PUT, PATCH, or DELETE.
- Return 412 when If-Unmodified-Since is earlier than the resource's last modification.
- Return 428 Precondition Required (RFC 6585) when the server requires a conditional request and the client did not send one.
Headers involved
- If-Match carries one or more ETags. The request proceeds only if one matches the current representation.
- If-Unmodified-Since carries a date. The request proceeds only if the resource has not changed since then.
- ETag in earlier responses gives the client the value to send in If-Match.
How to fix it
- GET the resource again to read the current ETag and state.
- Merge your change with the current state, then retry with the new ETag in If-Match.
- Do not drop the If-Match header to force the update through. That overwrites someone else's change.
Examples
Lost update prevented with If-Match
PUT /api/articles/31 HTTP/1.1
Host: api.example.com
If-Match: "v3"
Content-Type: application/json
{
"title": "Updated title"
}
HTTP/1.1 412 Precondition Failed
ETag: "v4"
Content-Type: application/json
{
"error": "The article changed since you loaded it. Reload and try again."
}
Common mistakes
- Returning 409 when the precondition header failed. 412 tells the client exactly which mechanism caught the conflict.
- Returning 412 for GET with If-None-Match. A matching If-None-Match on GET or HEAD returns 304 Not Modified, not 412.
- Comparing ETags with weak comparison for If-Match. RFC 9110 requires strong comparison for If-Match.
Developer notes
412 and 428 work as a pair. 428 tells clients that the server requires If-Match; 412 tells them their If-Match was stale. Together they stop lost updates, where two editors save over each other.
Questions
What does HTTP 412 Precondition Failed mean?
HTTP 412 means a condition in the request headers, such as If-Match, was false, so the server did not apply the request.
What is the difference between 412 and 428?
412 means the client sent a precondition that failed. 428 means the server requires a precondition and the client did not send one.
See also
Header and content rules
RFC 9110 adds no header or content rule specific to 412. The 4xx class rules also apply. See 412 in the response obligations table.