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 →
412428
Condition header sent?Yes, but it failedNo
MeaningResource changed since you read itServer requires conditional updates
FixRe-fetch, re-apply, retry with the new ETagGET first, then send If-Match: <etag>

Rule of thumb

428 → add If-Match. 412 → your copy is stale; refresh and retry.