412 Precondition Failed

A conditional header didn’t match.

When to use it

If-Match with an outdated ETag, to prevent lost updates.

Common causes and fixes

412 means a condition the client attached didn’t hold. Usually it is If-Match carrying an ETag that no longer matches, because someone else updated the resource first, and the server refuses to overwrite their change. The client should GET the current version, merge or ask the user, then retry with the new ETag. If-Unmodified-Since does the same with dates.

If-Match needs strong comparison, so weak ETags with the W/ prefix never match, and proxies that compress responses may weaken ETags, making every write fail with 412. The reverse, If-None-Match: * on a PUT, makes creation fail with 412 when the resource already exists, a cheap guard against overwriting. S3 and Google Cloud Storage use 412 for their conditional writes too.

Client error (4xx)

4xx codes are client errors: the request itself is wrong, unauthorised or points at something that isn’t there. Retrying the same request won’t help.

What it looks like

HTTP/1.1 412 Precondition Failed

How to send it

Node.js / Expressres.status(412).end()
Python / Flaskreturn '', 412
nginxreturn 412;

How to check it

curl -s -o /dev/null -w "%{http_code}\n" https://example.com/

Open HTTP Status Codes