Applies to: HTTP status 409 as defined in RFC 9110; examples tested with nginx 1.31.6 (WebDAV), the Docker Engine API 1.52 and PHP 8.3
409 Conflict means the server understood the request but won’t carry it out because it clashes with the current state of the thing you are changing. RFC 9110 says the request “could not be completed due to a conflict with the current state of the target resource”, in a situation where the user might be able to resolve the conflict and send it again. Typical cases are creating something that already exists, saving over a newer version, or uploading into a folder that doesn’t exist.
Unlike a 500 or 502 error, a 409 is usually not a server fault. The request needs to change, or the existing resource has to be dealt with first; sending the same request again unchanged normally gets the same answer.
Where you meet a 409
- APIs: creating a user, order or record whose unique field (email address, name, ID) is already taken.
- Edit conflicts: two people or scripts change the same record, and the second save is based on an old version.
- Docker: creating a container with a name that is in use. In our test the Engine API answered
HTTP/1.1 409 Conflict, and the CLI showed:Error response from daemon: Conflict. The container name "/k05-409" is already in use by container "c636b778ab11...". You have to remove (or rename) that container to be able to reuse that name.
- WebDAV: creating a folder whose parent folder doesn’t exist. RFC 4918 prescribes 409 because “a collection cannot be made at the Request-URI until one or more intermediate collections have been created.” Our nginx test returned
HTTP/1.1 409 ConflictforMKCOL /a/b/, and the error log saidmkdir() "/data/a/b" failed (2: No such file or directory).
How to fix it as a visitor or API user
- Read the response body. Most APIs explain the conflict, for example
{"error":"An account with this email already exists."}. - If something already exists, use it, rename yours, or delete the old one first (for Docker:
docker rm k05-409or choose another--name). - If it is an edit conflict, reload the latest version, apply your change to it and save again.
- For uploads, create the parent folders first, one level at a time.
- In a web app you don’t control, refresh the page and try again once; if it keeps happening, send the site owner the time and what you were doing.
How to return a 409 in your own application
Send 409 when the request is valid but can’t be applied to the current state. RFC 9110 says the server SHOULD include enough information for the user to recognise the source of the conflict, so explain it in the body. A PHP example we ran with PHP 8.3:
<?php
$existing = ['alice@example.com'];
$email = $_POST['email'] ?? '';
header('Content-Type: application/json');
if (in_array($email, $existing, true)) {
http_response_code(409);
echo json_encode(['error' => 'An account with this email already exists.']);
exit;
}
http_response_code(201);
echo json_encode(['created' => $email]);
Posting alice@example.com returned HTTP/1.1 409 Conflict; posting a new address returned HTTP/1.1 201 Created.
409 compared with similar codes
- 400 Bad Request: the request itself is malformed. See 400 Bad Request.
- 422 Unprocessable Content: the data is well-formed but fails validation, such as a bad email format. See 422 Unprocessable Content.
- 412 Precondition Failed: the client sent a condition, such as
If-Matchwith a version tag, and it “evaluated to false when tested on the server” (RFC 9110). An API that usesIf-Matchanswers a stale edit with 412 instead of 409. - 405 Method Not Allowed: the method isn’t accepted for that URL at all. Our nginx WebDAV test answered 405, not 409, to
MKCOLon a folder that already existed. See 405 Method Not Allowed.
Other status codes: 401 Unauthorized and 502 Bad Gateway.
Official documentation: RFC 9110: 409 Conflict.