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

Monitor your API health

Track precondition failures and API errors.

Start monitoring free →

Related Status Codes