428 Precondition Required
4xx client error
The server requires the request to be conditional, such as with If-Match, to prevent lost updates.
428 (RFC 6585) forces clients into safe concurrent editing. The server refuses unconditional writes: you must send If-Match with the ETag you last saw, so your update can't silently overwrite someone else's.
| Class | 4xx Client Error |
|---|---|
| Retry? | No — change the request first |
| Cacheable by default | No — only with explicit Cache-Control |
| Response body | Allowed |
| Defined in | RFC 6585 §3 — 428 Precondition Required |
Example response
HTTP/1.1 428 Precondition Required
Content-Type: application/json
Content-Length: 33
{"error":"Precondition Required"}Common causes
- A PUT, PATCH or DELETE without
If-Match, sent to an API that enforces optimistic concurrency.
How to fix it
- GET the resource, read its
ETag, and send it asIf-Matchon the write. - Be ready to handle 412 if the resource changed in between.
Send a 428 from your server
Express
res.status(428).json({ error: "Precondition Required" });Next.js route handler
return Response.json({ error: "Precondition Required" }, { status: 428 });Flask
return {"error": "Precondition Required"}, 428Go net/http
http.Error(w, "Precondition Required", http.StatusPreconditionRequired)
nginx
return 428;
Check what a URL returns
Print just the status line from the command line, or check a whole list of URLs at once, with their response headers, in the HTTP Status Checker.
curl -sI https://example.com/your-path | head -n 1
Frequently asked questions
428 vs 412?
428: you didn't send a precondition and the server requires one. 412: you sent one and it failed.
Headers used with 428
Related status codes