412 Precondition Failed: what it means and what to do
A 412 is the server reporting that a condition attached to the request did not check out. Under RFC 9110, a client can send preconditions in headers such as If-Match, If-None-Match, If-Unmodified-Since, and If-Modified-Since, saying in effect: only do this if the resource is still in the state I expect. When one of those conditions evaluates to false, the server must refuse and answer 412 Precondition Failed. It is almost entirely an API error, and it exists to stop one client from blindly overwriting another client's changes.
If you ran into this as a user
- Refresh and try again. In apps that use preconditions behind the scenes, a 412 usually means the thing you were editing changed while you worked. Reloading fetches the current version and its fresh state marker.
- Save your work aside first if you typed anything substantial. Reloading can discard your edits.
- If it repeats, sync or sign in again. Stale cached state on the client side can keep sending an outdated version marker. A full reload or fresh sign-in replaces it.
If it is your API
- Log which precondition failed. The header values and the resource's current ETag tell the whole story. A client holding an old ETag is normal after someone else edits; a client that never had a valid one is a bug.
- Remember the evaluation order. RFC 9110 specifies the sequence in which preconditions are checked when several are present. Getting it wrong produces 412s that should have been 304s, and vice versa.
- Do not use 412 for ordinary validation. It has a precise meaning tied to conditional headers. Business-rule failures belong in 409 or 422.
- Document your concurrency model. If you require If-Match for updates, say so loudly. Clients cannot guess that their missing header, rather than their data, is the problem.
Everyone: a 412 is a safeguard firing, not data loss. The server refused a change because the resource had moved on from the state the request assumed.
Common questions
What is an ETag and why does it matter here? An ETag is a version marker the server attaches to a resource. Clients send it back in If-Match to prove they are editing the version they read. If the resource changed, the ETags no longer match and the server answers 412 instead of overwriting the newer version.
What is the difference between 412 and 409? A 412 is specifically about conditional request headers evaluating to false. A 409 is the broader state-conflict code, used when the application detects a clash itself rather than through a precondition header.
Related errors