Skip to content
Webmaster Tools

409 Conflict

What HTTP 409 Conflict means in REST APIs, typical causes such as duplicate records and version mismatches, how clients resolve it, and when to use 412 or 422.

All status codes

What 409 means

The request is valid, but it conflicts with the current state of the resource, so the server can't apply it. 409 is defined in RFC 9110 §15.5.10, which expects the conflict to be something the client can resolve and asks the server to explain it in the body:

HTTP/1.1 409 Conflict
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/duplicate-email",
  "title": "Email already registered",
  "detail": "An account with ana@example.com already exists."
}

The application/problem+json format (RFC 9457) is a good default for that body.

Common causes

  • Duplicates: creating a user, slug or bucket whose unique value is already taken. S3 answers 409 BucketAlreadyExists.
  • Edit conflicts: two clients update the same record and the second one is working from a stale version. Kubernetes answers 409 when an update carries an old resourceVersion.
  • Invalid state transitions: cancelling an order that has already shipped, deleting a non-empty bucket (BucketNotEmpty), merging a branch that has conflicts (the GitHub API answers 409).
  • Retried creates: a POST that succeeded but timed out is sent again and now hits its own first copy.

How to fix it as a client

  1. Read the body. It should say which value or version conflicts.
  2. For version conflicts, fetch the latest copy, reapply your change on top of it, and send it again. Don't retry blindly: the same request will conflict again.
  3. For duplicates, treat "already exists" as success when that's what you wanted (an idempotent create), or ask the user for a different value.
  4. Make creates idempotent with a client-generated ID or an Idempotency-Key header where the API supports it, so a retried POST doesn't conflict with itself.

How to send it as a server

Use 409 when the request is well-formed and valid on its own but clashes with stored state. Two neighbours fit better in specific cases:

Map the database's unique-constraint error to 409 in one place instead of letting it surface as a 500.

409 and SEO

409 comes from APIs and form submissions, which search engines don't crawl, so it rarely matters for SEO. If a public page answers 409 to GET, Google treats it like any 4xx other than 429: the URL isn't indexed. Pages meant for search should answer 200.

To reproduce a conflict, send the same request twice with the HTTP Request Builder and compare the responses.