
A 409 Conflict error means the server understood your request, but it can't process it because it conflicts with the current state of the target resource. This is one of the more specific HTTP error codes — it's telling you not just that something went wrong, but that the data you're trying to submit clashes with what already exists.
You'll encounter 409 errors most often in APIs, version-controlled systems, and applications where multiple users or processes can modify the same resource simultaneously.
A 409 status code indicates that the request could not be completed due to a conflict with the resource's current state. The server is saying: "I understand what you want to do, and I could do it under different circumstances, but right now there's a conflict that prevents it."
Unlike a 422 Unprocessable Entity where the data itself is malformed, a 409 means the data is valid — it just clashes with something that already exists or with a business rule.
Common scenarios:
The most common trigger. Your application tries to create a resource that already exists or violates a unique constraint.
# Example: trying to create a user with a duplicate email
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]", "name": "New User"}'
# Response: 409 Conflict
# {"error": "A user with this email already exists"}
This typically maps to a database uniqueness violation:
# PostgreSQL error behind the scenes
# ERROR: duplicate key value violates unique constraint "users_email_key"
Many APIs use optimistic locking to prevent lost updates. When you fetch a resource, you receive a version identifier (often an ETag or a version number). When you update it, you send that version back. If someone else updated the resource in the meantime, the versions don't match and you get a 409.
# Fetch the resource with its ETag
curl -i https://api.example.com/documents/123
# ETag: "v5"
# Try to update with the ETag
curl -X PUT https://api.example.com/documents/123 \
-H "If-Match: v5" \
-H "Content-Type: application/json" \
-d '{"title": "Updated Title"}'
# If someone else updated it (now at v6), you get 409
Some resources follow a specific lifecycle. For example, you can't cancel an order that's already been delivered, or you can't publish a document that's been archived. Attempting an invalid state transition returns a 409.
Version control systems and file storage APIs return 409 when you try to push changes that conflict with the current state. Git users will recognise this as the API equivalent of a merge conflict.
Two requests hitting the server at nearly the same time, both trying to modify the same resource. The first one succeeds; the second gets a 409 because the resource's state changed between when the request was composed and when it was processed.
A well-designed API will tell you exactly what the conflict is. Check the response body:
curl -s -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}' | jq .
The response should explain whether it's a duplicate key, a version mismatch, or a state conflict.
If you're hitting unique constraint violations, check if the resource exists before trying to create it, or use an upsert pattern:
# Check if the resource exists first
curl -s -o /dev/null -w "%{http_code}" https://api.example.com/users?email=[email protected]
On the server side, many databases support "insert or update" operations:
-- PostgreSQL upsert
INSERT INTO users (email, name) VALUES ('[email protected]', 'Test User')
ON CONFLICT (email) DO UPDATE SET name = EXCLUDED.name;
For optimistic locking conflicts, the standard fix is to re-fetch the resource, get the latest version, apply your changes, and retry:
# 1. Fetch the latest version
curl -i https://api.example.com/documents/123
# Get the new ETag from the response
# 2. Retry the update with the new ETag
curl -X PUT https://api.example.com/documents/123 \
-H "If-Match: v6" \
-H "Content-Type: application/json" \
-d '{"title": "Updated Title"}'
If you're getting 409s from invalid state transitions, check the resource's current state before attempting the operation:
# Check the current state
curl -s https://api.example.com/orders/456 | jq '.status'
# "delivered"
# Don't try to cancel a delivered order
On the server side, catch constraint violations and return meaningful 409 responses:
# Check your application logs for the underlying database error
grep -i "duplicate key\|unique constraint\|conflict" /var/log/app/error.log
While 409 errors are typically application-level issues rather than infrastructure failures, a sudden spike in 409 responses can indicate a deeper problem — such as a corrupted database index, a race condition introduced by a new deployment, or a misconfigured API endpoint returning 409 for all requests instead of just conflicting ones.
Domain Monitor checks your endpoints every minute from multiple locations worldwide. If your API or web application starts returning 409 errors (or any unexpected status codes) where it should be returning 200s, you'll be alerted immediately via email, SMS, or Slack. You can set up downtime alerts for your critical endpoints and use website monitoring to ensure your application is responding correctly across all regions.
| Cause | Fix |
|---|---|
| Duplicate resource (unique constraint) | Check existence first, or use upsert |
| Optimistic locking mismatch | Re-fetch, get latest version, retry |
| Invalid state transition | Check resource state before the operation |
| Race condition | Implement proper locking or retry logic |
| File/version conflict | Merge changes, then resubmit |
A 409 is one of the more helpful HTTP errors — it tells you specifically that there's a data conflict, not just a vague server error. Read the response body, resolve the conflict, and retry.
Wildcard, SAN (multi-domain), and single-domain SSL certificates cover different use cases. Here's a clear comparison to help you pick the right type — and avoid paying for coverage you don't need.
Read moreDNS resolves correctly from your office but fails for users in other countries or on different ISPs. Here's why geographic DNS inconsistency happens and how to diagnose which layer is causing it.
Read moreRegistrar lock and transfer lock are often confused — and disabling the wrong one leaves your domain vulnerable. Here's a clear breakdown of what each does and when to use them.
Read moreLooking to monitor your website and domains? Join our platform and start today.