428 Precondition Required
The server requires the request to be conditional, so unconditional writes are rejected.
Status
HTTP/1.1 428 Precondition Required
Details
- Category: 4xx
- Status: Standard. Registered with IANA and defined by a current standards-track RFC.
- Specification: RFC 6585 §3
- Cacheable: Not cacheable
- Response body: Allowed
- Retry: Retry only after changing the request
428 closes the lost update hole. Without it, two clients can each read a resource, each write it back, and the second write silently discards the first. A server that returns 428 is insisting on If-Match so that a stale write fails with 412 instead of overwriting.
The response should explain which precondition is expected. Clients then re-read the resource, take its ETag, and resend the write conditionally.
Headers
- If-Match: The request header the server expects, carrying the ETag of the version being replaced.
Common causes
- A PUT or PATCH sent without If-Match to an endpoint that requires optimistic concurrency.
- A client library that drops conditional headers on retries.
How to fix it
As the client
- GET the resource, read its ETag, and resend with If-Match set.
- Keep the ETag with your local copy so writes can always be made conditional.
As the server
- Name the required header in the error body.
- Emit stable ETags on the GET path, otherwise clients cannot satisfy the requirement.
Examples
PUT /api/docs/91 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{"title":"Updated"}
HTTP/1.1 428 Precondition Required
Content-Type: application/json; charset=utf-8
{"error":"precondition_required","expected":"If-Match"}