A 409 error code means the server sees a conflict with the resource’s current state, so it won’t apply your request as-is.
A 409 usually shows up when two things try to change the same resource at the same time, or when your request is valid but clashes with rules about the resource’s current version. You’ll see it in APIs, admin dashboards, Git workflows, and web apps that track versions.
Here’s 409 error code meaning in plain terms, plus the fixes that usually stop it.
If you just want the plain idea, here it is. The server understood your request. It’s refusing the change because it can’t apply it cleanly against what exists right now.
What A 409 Error Code Means In Plain Terms
HTTP status code 409 is named “Conflict.” The definition in the HTTP Semantics spec is straightforward: the request can’t be completed due to a conflict with the current state of the target resource. When a server returns 409, it’s telling you the request is not the problem; the state you’re trying to change is. (RFC 9110)
In practical terms, a 409 response often means one of these situations is true:
- You’re updating stale data — Your app fetched a resource, someone else changed it, then your app tried to save an older version.
- You’re creating a duplicate — Your request tries to create something that already exists under a no-duplicate rule.
- You’re breaking a state rule — The resource is in a state where your action can’t happen yet, like trying to publish a draft that failed validation earlier.
A 400 means the server can’t parse what you sent. A 401 or 403 means you don’t have access. A 404 means the target isn’t there. A 409 means the target is real, but the state doesn’t match. (MDN 409 Conflict)
409 Error Code Meaning For REST APIs And Sites
Most people run into 409 in one of two places: API updates and admin-style web apps. In both, the pattern is the same. You try to change something, and the server refuses because your change collides with a newer version or a rule that’s enforced at write time.
In a REST API, 409 commonly appears on PUT, PATCH, or POST requests. It can show up on DELETE too, like when a record can’t be removed because it’s referenced by another record. The response body often includes a short error message that names the conflict, plus a code your client can act on.
In a browser-based app, you might see “409 Conflict” in the network tab while saving a form. You might see a friendlier message in the UI, like “This item was updated elsewhere” or “Name already taken.”
When 409 Is The Right Choice
APIs use 409 when the client could retry after resolving the conflict. That “resolve” step may be as simple as fetching the latest version, re-applying your change, and submitting again. In systems that use optimistic concurrency control, 409 is often paired with version fields, ETags, or conditional requests using If-Match.
Common Triggers Behind A 409 Conflict
If you treat 409 as “a random server glitch,” you’ll waste hours. The fastest fix is to match the error to the most common triggers and test them one by one.
Concurrent Updates And Race Conditions
Two clients read the same record, then both try to update it. The first update succeeds. The second update arrives with an older version and gets rejected. This is the classic “last write wins” problem, except the server is refusing to let the last write silently overwrite newer data.
- Fetch the latest version — Read the resource again and capture its current version or ETag.
- Merge your changes — Apply your edits on top of the newest state.
- Retry the update — Send the write request again with the updated version details.
No-Duplicate Rules And Repeat Creates
A 409 can happen when you POST a new resource that violates a no-duplicate rule. Usernames, slugs, email values, order numbers, and external IDs often have no-duplicate indexes in the database. The server can’t accept the new resource without breaking that rule.
- Regenerate the identifier — Create a new slug or ID and retry.
- Switch to idempotency — Use an idempotency token so retries don’t create duplicates.
- Check before create — Query for the existing resource and route to an update flow when it exists.
State Rules And Workflow Locks
Some conflicts aren’t about concurrency; they’re about state. A payment can’t be refunded twice. A shipment can’t be “shipped” if it’s already “delivered.” A file can’t be updated if the platform requires the latest revision hash. GitHub’s “create or update file contents” endpoint is a common place to see this kind of 409 if you send an outdated SHA for the file you’re updating. (GitHub thread)
Quick Checks To Pinpoint The Conflict
When you see 409, don’t guess. You can usually isolate the cause in a few minutes if you run a tight set of checks.
Check The Response Body And Headers
Start with the response payload. Many APIs return a structured JSON error with a machine-friendly code, a human message, and a hint about what field or version caused the rejection. Then scan response headers for ETag or version markers that can guide your next request.
- Read the error code — Look for a field like
error,code, orreasonthat names the conflict type. - Capture the ETag — If the response includes ETag, store it and use it in a conditional update.
- Log the request IDs — Correlate client logs with server logs using request IDs when available.
Confirm You’re Targeting The Right Resource
409 can be a symptom of sending the right payload to the wrong URL. Double-check the resource ID, path parameters, and tenant or workspace identifiers. One small mismatch can land your update in a resource that has different rules, different version state, or a different no-duplicate scope.
Look For Retries And Duplicate Submits
Browsers can resend requests after a flaky connection. Mobile clients can retry in the background. Load balancers can replay requests in edge cases. If you see multiple identical write requests inside a tight window, you might be creating your own conflict.
- Search logs by fingerprint — Match requests by method, path, and body hash.
- Check retry middleware — Review client libraries that auto-retry writes on timeouts.
- Add an idempotency token — Use a stable token per user action so repeats become safe.
Use A Simple Conflict Map
This table helps you match common 409 patterns to what to try next. Keep it close while you debug.
| Where You See 409 | What It Usually Means | First Fix To Try |
|---|---|---|
| PUT/PATCH update | Stale version or missing precondition | Re-fetch, then retry with version/ETag |
| POST create | Duplicate under a no-duplicate rule | Generate a new ID or handle as update |
| DELETE request | Blocked by references or workflow rules | Remove dependencies, then retry |
Fixes That Work For Developers And Site Owners
Once you know the trigger, the fix is usually mechanical. The goal is to bring your request back in sync with the server’s current state, or to change your workflow so the conflict never happens.
Developer Fixes For API Clients
If you’re writing the client, treat 409 as a prompt to reconcile state. That can mean reloading data, merging changes, or prompting the user to decide which version should win.
- Retry with fresh state — GET the resource, apply your intended change, then resend the PUT or PATCH.
- Send conditional updates — Use ETag with If-Match so the server only applies your write to the version you saw.
- Design safe retries — Add idempotency tokens to POST requests so retries don’t create duplicates.
- Handle merges in one place — Centralize conflict resolution logic so each endpoint doesn’t reinvent it.
Developer Fixes For API Servers
If you own the server, a helpful 409 response can save your users. Add details that let a client fix the issue without a ticket.
- Return a structured error payload — Include a stable error code, a short message, and conflict fields like
expectedVersion. - Expose version signals — Provide ETag headers or version numbers on reads and writes.
- Document the retry path — Explain whether clients should re-fetch, merge, or prompt a user.
Fixes For WordPress And Web App Owners
If you’re seeing “409 Conflict” while using WordPress, a headless CMS, or a plugin-heavy admin panel, you may not control the API. You can still reduce conflicts by narrowing down what triggers them.
- Refresh the page before saving — Reload the editor to pull the newest revision, then redo the change.
- Clear cached requests — Empty browser cache and disable aggressive caching plugins for the admin area.
- Turn off one plugin at a time — Conflicts can come from two plugins writing the same settings record.
- Check REST API security rules — WAF rules and security plugins can block certain write patterns and return 409-like responses.
Preventing 409 Conflicts In New Work
When you design for conflict up front, 409 becomes rare and boring. The main idea is simple: make it hard to overwrite newer data and easy to reconcile when a clash happens.
Choose A Clear Concurrency Strategy
Many systems use optimistic concurrency, where clients send a version marker with updates. The server rejects stale writes with 409 or 412. This keeps write paths fast and avoids long locks.
- Add ETags to GET responses — Let clients store the ETag and reuse it on updates.
- Require If-Match on updates — Reject writes that don’t prove they’re based on a current version.
- Return the latest resource on conflict — Include the current state in the 409 payload when it’s safe to do so.
Make Creates Idempotent
When networks drop or users double-click, idempotency keeps your data clean. A server can accept a request once, then treat repeats as the same operation.
- Accept an idempotency token — Use a header or field like
Idempotency-Tokenand store outcomes for a short window. - Use natural identifiers carefully — If a resource is identified by email or external ID, treat a second create as a read-or-update flow.
- Debounce UI actions — Disable submit buttons after click until the request completes.
Write Error Messages That Lead To A Fix
A vague “Conflict” message forces guesswork. A good message tells the user what changed and what to do next. It can be short and still useful.
- Name the conflicting field — Say “slug already exists” or “version mismatch” instead of a generic error.
- Tell the next step — Suggest “refresh to load the latest version” or “pick a new name.”
- Keep sensitive details out — Share only what the user needs to resolve the issue.
If you came here searching for 409 error code meaning, the pattern to remember is conflict with current state. Fix the mismatch, then retry. If you’re documenting an API, make that path obvious so clients can resolve 409 errors without guesswork.
