412 Precondition Failed
A conditional header on the request, such as If-Match or If-Unmodified-Since, evaluated to false, so the server did not perform the action.
At a glance
- Status code
- 412 Precondition Failed
- Class
- 4xx, client error, the request itself is the problem
- Defined in
- RFC 9110
- Cacheable by default
- no
- Response body
- Optional.
In detail
The client said only do this if the resource is still in the state I saw. It was not, so nothing happened. This is the safe half of optimistic locking.
Support If-Match on every unsafe method that can suffer a lost update. Without it, two concurrent edits silently overwrite each other.
Re-fetch the resource, look at the new ETag and content, decide whether the change still applies, then retry with the fresh validator.
Examples
HTTP/1.1 412 Precondition Failed
ETag: "9a1f"
Content-Length: 0Things that catch people out
- 412 means nothing was changed. That is the guarantee it exists to give, and code that retries without re-reading throws it away.
- If-None-Match on a GET produces 304 rather than 412. The code depends on the method and the header, not on the failure alone.
Try it: HTTP Request Builder
Build a request with any method, headers and body, send it, and read the status line the server returns.
HTTP Request Builder
LOCAL · Browser-OnlyBuild and test HTTP requests with custom headers and body
Authentication
Headers
Generate Code
curl -X GET 'https://api.example.com/endpoint' \
-H 'Content-Type: application/json'Showing a sample URL. Enter your endpoint above to update the snippet.
Related HTTP status codes
All http status codes →409 Conflict
The request clashes with the current state of the resource, for example an edit based on a version that has since changed.
304 Not Modified
The cached copy the client already holds is still current, so the server sent no body. This is what makes conditional requests cheap.
428 Precondition Required
The server requires the request to be conditional, and refuses an unconditional one to prevent a lost update.
413 Content Too Large
The request body is larger than the server is willing to process. Formerly called Payload Too Large.
414 URI Too Long
The request URL is longer than the server will accept. Almost always caused by putting data in a query string that belongs in a request body.
415 Unsupported Media Type
The server refuses the request because the body is in a format it cannot handle, as declared by Content-Type.
Tools for this
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL