412 Precondition Failed: Conditional Request Rejected
If-Match, If-None-Match, If-Modified-Since, or If-Unmodified-Since. The server rejects the request because the preconditions evaluated to false. This is often used in optimistic locking: the client sends an If-Match header with an ETag, and the server checks if the current ETag matches β if not, it returns 412, indicating the resource has been modified elsewhere.
Common Precondition Headers
| Header | Purpose | When 412 Occurs |
|---|---|---|
| If-Match | Only perform the request if the resource's ETag matches the given value. | ETag does not match (resource has changed). |
| If-None-Match | Only perform the request if the resource's ETag does NOT match the given value. | ETag matches (resource is unchanged, but client expected change). |
| If-Modified-Since | Only perform the request if the resource has been modified since the given date. | Resource has not been modified since that date. |
| If-Unmodified-Since | Only perform the request if the resource has NOT been modified since the given date. | Resource has been modified since that date. |
Example: If-Match for Optimistic Locking
A client attempts to update a resource using an If-Match header with an ETag it previously received:
The client should GET the latest version, merge its changes, and retry with the new ETag.
412 vs. 409 Conflict
| Status | When It Happens | Typical Use |
|---|---|---|
| 412 Precondition Failed | Before attempting the operation β preconditions fail. | Strict conditional requests (e.g., PUT with If-Match). |
| 409 Conflict | During or after attempting the operation β state conflict. | More general conflict (e.g., duplicate key, state machine violation). |
In practice, many APIs use 409 for both cases because it provides more flexibility and is better supported by clients. However, 412 is the correct status when the failure is specifically due to a precondition header.
When to Use 412
- For idempotent updates β to prevent lost updates in concurrent environments.
- For caching β
If-None-MatchandIf-Modified-Sinceare used to validate cached responses (usually returns 304 Not Modified, not 412). - For optimistic locking β ensuring the client's version matches the current version before applying changes.
How to Fix 412 Errors
- If you're a client developer: Retrieve the latest version of the resource (GET), merge your changes, and retry with the new ETag. If you're using conditional requests for caching, simply use your cached copy if 412 is returned (or handle the 304 response).
- If you're a server developer: Ensure your server correctly handles conditional headers and returns 412 when preconditions fail. Provide helpful error messages that include the current ETag or last modified date.
- If you're an endβuser: This error usually means the resource has been updated by someone else. Refresh the page and try again.
Frequently Asked Questions
Is 412 Precondition Failed a client error or a server error?
It's a client error (4xx). The client's conditional headers did not match the server's current state, so the request cannot be fulfilled as specified.
What is an ETag and why is it used?
An ETag (entity tag) is a unique identifier for a specific version of a resource. It is used in conditional requests to detect changes. If the ETag changes, the resource has been modified.
Can I use 412 for validation errors?
No, 412 is specifically for precondition failures. For validation errors, use 422 Unprocessable Entity.