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 exist:

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 changed 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 conflicts when multiple people are writing to the same resource and overwriting each other’s changes. 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

Web mentions