412 vs 428: Precondition Failed vs Precondition Required
Both protect against lost updates. 428 means you didn’t send a condition at all; 412 means you sent one (If-Match) and it no longer matches.
412
HTTP 412 Precondition Failed
A conditional request header (If-Match, If-Unmodified-Since) didn’t match the current state of the resource.
Causes & fixes →
428
HTTP 428 Precondition Required
The server requires a conditional request (If-Match / If-Unmodified-Since) to prevent lost updates, and you didn’t send one.
Causes & fixes →| 412 | 428 | |
|---|---|---|
| Condition header sent? | Yes, but it failed | No |
| Meaning | Resource changed since you read it | Server requires conditional updates |
| Fix | Re-fetch, re-apply, retry with the new ETag | GET first, then send If-Match: <etag> |
Rule of thumb
428 → add If-Match. 412 → your copy is stale; refresh and retry.