412 Precondition Failed

Client Error - Conditional request precondition not met

HTTP 412 Precondition Failed

What It Means

The HTTP 412 Precondition Failed status code indicates that one or more conditions given in the request headers (like If-Match or If-Unmodified-Since) evaluated to false on the server.

Common Precondition Headers

Header Purpose
If-Match Only proceed if ETag matches (optimistic locking)
If-Unmodified-Since Only proceed if not modified since date
If-None-Match Used for caching (returns 304 if match)

Example: Optimistic Locking

# Client has ETag "abc123" from previous GET
PUT /api/documents/1 HTTP/1.1
If-Match: "abc123"
Content-Type: application/json

{"title": "Updated Title"}

---

# If document was modified by someone else (ETag changed):
HTTP/1.1 412 Precondition Failed
Content-Type: application/json

{
  "error": "Precondition Failed",
  "message": "Document was modified. Your ETag: abc123, Current: def456"
}

412 vs 409

  • 412: Header-based precondition failed (If-Match, etc.)
  • 409: Business logic conflict (duplicate email, etc.)

Implementation

app.put('/api/documents/:id', async (req, res) => {
  const ifMatch = req.headers['if-match'];
  const doc = await Document.findById(req.params.id);

  if (ifMatch && ifMatch !== doc.etag) {
    return res.status(412).json({
      error: 'Precondition Failed',
      message: 'Document was modified by another request',
      currentETag: doc.etag
    });
  }

  // Proceed with update
  doc.title = req.body.title;
  doc.etag = generateNewETag();
  await doc.save();

  res.set('ETag', doc.etag);
  res.json(doc);
});

Use Cases

  • Preventing lost updates: Don't overwrite concurrent changes
  • Conditional uploads: Only upload if file doesn't exist
  • Safe deletes: Only delete if resource is unchanged

Frequently Asked Questions

What does HTTP 412 Precondition Failed mean?
HTTP 412 Precondition Failed means one or more conditions specified in the request headers (such as If-Match or If-Unmodified-Since) were not met by the server. This is commonly used in optimistic locking to prevent overwriting changes made by another user.
What is the difference between 412 and 409?
412 Precondition Failed is triggered by HTTP conditional headers like If-Match and If-Unmodified-Since. 409 Conflict is triggered by business logic conflicts like duplicate entries or version mismatches in the request body. Use 412 for header-based preconditions and 409 for application-level conflicts.
How does If-Match work with ETags?
The client sends an If-Match header containing an ETag value received from a previous GET request. Before processing the update, the server compares this ETag with the current ETag of the resource. If they do not match, someone else has modified the resource, and the server returns 412.
How do I handle a 412 error in my client code?
When you receive a 412, fetch the latest version of the resource with a new GET request, get the updated ETag, merge your changes with the current state, and retry the update with the new ETag in the If-Match header. This is the standard optimistic concurrency pattern.

Monitor your API health

Track precondition failures and API errors.

Start monitoring free →

Related Status Codes

More Resources