412 Precondition Failed

In HTTP it’s possible to do conditional requests. These are requests that only execute if the right conditions are met.

For GET requests, this might be done to only retrieve the resource if it has changed. For those cases 304 Not Modified is returned.

For other cases, 412 Precondition Failed is returned.


This client only wants the PUT request to succeed, if it didn’t already exit:

PUT /foo/ HTTP/1.1
Content-Type: text/markdown
If-None-Match: *

This request is an update, and it should only succeed if the article hasn’t change since last time.

PUT /foo/ HTTP/1.1
If-Match: "1345-12315"
Content-Type: text/markdown

If the condition didn’t pass, it returns:

HTTP/1.1 412 Precondition Failed
Content-Type: text/plain

The article you're tring to update has changed since you last seen it.

One great advantage of this is that prevents lost updates, due to multiple people writing to the same resource. This is also known as the ‘lost update’ problem.

Using the Prefer header, it’s possible for a client to get the current state of the resource, in case the local copy was outdated. This saves a GET request.

PUT /foo/ HTTP/1.1
If-Match: "1345-12315"
Content-Type: text/markdown
Prefer: return=representation

### Article version 2.1
HTTP/1.1 412 Precondition Failed
Content-Type: text/markdown
Etag: "4444-12345"
Vary: Prefer

### Article version 3.0

This is useful, but it should probably have been designed with a HTTP/2 Push message instead. Nevertheless, there’s no harm in adopting this for legacy HTTP/1.1 systems.


HTTP series

This article is part of a series about the HTTP protocol. Read them all here:

Informational 1xx

Successful 2xx

Redirection 3xx

Client Error 4xx

Server Error 5xx

Bad Gateway is Toronto-based team of software engineers. We build good APIs and websites.

Want to work with me on your next project?

Email us

Web mentions