412 Precondition Failed
The HTTP 412 Precondition Failed status code is a client error returned by the server to indicate one or more client-specified conditions in the request have failed. Due to this failure, the request was not completed.
Usage
When the 412 Precondition Failed error message is received, the client knows one or more conditions specified in the request failed, and the resource was not in the expected state. The specific behavior depends on the precondition header. An If-Match failure returns 412 for any method. An If-None-Match failure returns 304 for GET and HEAD, and 412 for all other methods.
This is similar to 304, though in the 304 case a resource was not sent because the client already had the most recent version available, and a subsequent transmission is unnecessary.
SEO impact
Search engines like Google will not index a URL with a 412 response status. URLs previously indexed will be removed from search results.
Example
The client wants to reply to a blog post, but only under the condition the post has not been changed since the client last viewed the resource. The condition is contained as part of the If-Unmodified-Since header. When the condition fails, the resource has been modified, and the server responds with 412 Precondition Failed to indicate the request was not completed.
By following this protocol, the problem of a "lost update" is avoided. Lost updates occur when multiple clients write to the same resource, and one or more work with an outdated version. By ensuring the resource has not been modified, overwrites of data changed in the interim are prevented.
Request
POST /blog/update?postid=111&task=reply HTTP/1.1
Host: www.example.re
If-Unmodified-Since: Fri, 1 Jan 2021 00:00:00 GMT
Content-Type: text/plain
Content-Length: 45
<Message body contains reply-text from the client>
Response
HTTP/1.1 412 Precondition Failed
Content-Type: text/html
Content-Length: 139
<html>
<head>
<title>Blog Update Error</title>
</head>
<body>
<p>The post has changed since last viewed.</p>
</body>
</html>
How to fix
Fetch the current version of the resource with a GET or HEAD request to obtain the latest ETag or Last-Modified value. Replace the stale validator in the If-Match or If-Unmodified-Since header with the current one and retry the request.
When using optimistic concurrency control (common in REST APIs and CMS platforms), the workflow is:
- Fetch the resource and store the ETag from the response
- Send the update with
If-Match: <stored ETag> - On a 412, re-fetch the resource, merge changes if needed, and retry with the new ETag
Clearing the browser cache resolves 412 errors caused by stale cached validators. The browser holds an outdated ETag or timestamp and attaches old conditional headers to requests automatically.
Caching proxies and CDNs between client and origin server sometimes serve stale validators. Verify proxy configurations pass conditional headers through without modification. AWS CloudFront, for example, returns 412 when an If-Match header on a GET request does not match the object's ETag. In these cases, confirm the CDN cache is fresh or invalidate the distribution.
Code references
.NET
HttpStatusCode.PreconditionFailed
Rust
http::StatusCode::PRECONDITION_FAILED
Rails
:precondition_failed
Go
http.StatusPreconditionFailed
Symfony
Response::HTTP_PRECONDITION_FAILED
Python3.5+
http.HTTPStatus.PRECONDITION_FAILED
Java
java.net.HttpURLConnection.HTTP_PRECON_FAILED
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_PRECONDITION_FAILED
Angular
@angular/common/http/HttpStatusCode.PreconditionFailed
Takeaway
The 412 Precondition Failed status code is a client error indicating one of the specified conditions has failed and the request will not be completed. This protects against lost updates when multiple clients modify the same resource.
See also
- RFC 9110: HTTP Semantics
- Google: HTTP status codes and network errors
- 304
- If-Unmodified-Since
- If-Match
- Conditional requests
- HTTP status codes
- HTTP headers