Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Kubernetes & Helm By James Joyner IV · · 9 min read

Kubernetes Error Guide: 'Error from server (Conflict)' Object Has Been Modified

Fix Error from server (Conflict): the object has been modified. Understand optimistic concurrency, resourceVersion, and how to retry kubectl edits and patches.

  • #kubernetes-helm
  • #troubleshooting
  • #errors
  • #api-server

Exact Error Message

When two writers update the same object concurrently, the API server rejects the second write with HTTP 409 and a Conflict status error that names the object and the optimistic-concurrency failure:

Error from server (Conflict): Operation cannot be fulfilled on deployments.apps "checkout": the object has been modified; please apply your changes to the latest version and try again

You will also see it from kubectl edit and controllers:

Error from server (Conflict): Operation cannot be fulfilled on resourcequotas "compute": the object has been modified; please apply your changes to the latest version and try again

The Conflict reason and the phrase the object has been modified are the signatures of an optimistic-concurrency collision.

What the Error Means

Every Kubernetes object carries a metadata.resourceVersion — an opaque, monotonically advancing token that changes on every write. When you read an object, you get its current resourceVersion; when you write it back (update/PUT or kubectl edit), the server checks that the version you are submitting still matches the version stored in etcd. If something else wrote to the object in between, the stored version advanced, your submitted version is now stale, and the server refuses the write with Conflict.

This is optimistic concurrency control. Instead of locking objects, Kubernetes lets everyone read freely and detects collisions at write time. The error is not a bug — it is the system protecting you from blindly overwriting another writer’s change (a controller’s status update, an HPA scaling event, another operator). The fix is almost always to re-read the latest object and re-apply your change on top of it.

Common Causes

  • Concurrent controller writes — a controller (HPA, deployment controller, an operator) updated the object’s status or spec while you were editing it.
  • Slow kubectl edit — you held the editor open long enough for another writer to change the object.
  • Stale read-modify-write in code — a client GETs, mutates, and PUTs using an old resourceVersion.
  • Two controllers fighting — two operators reconcile the same object and overwrite each other in a loop.
  • High-churn objects — status-heavy objects (ResourceQuota, Endpoints, leases) change constantly, so any non-trivial edit window collides.
  • Retry storms — a failed apply retried without re-reading the object keeps resubmitting the stale version.

How to Reproduce the Error

Open an object for editing, change it elsewhere, then save:

# Terminal 1: open the deployment in an editor and pause before saving
kubectl edit deployment checkout

# Terminal 2 (while the editor is still open): bump the replicas
kubectl scale deployment checkout --replicas=4

Now save and close the editor in terminal 1:

error: deployments.apps "checkout" is invalid
Error from server (Conflict): Operation cannot be fulfilled on deployments.apps "checkout": the object has been modified; please apply your changes to the latest version and try again

The scale advanced the resourceVersion, so the editor’s stale version was rejected.

Diagnostic Commands

# Read the current resourceVersion of the object
kubectl get deployment checkout -o jsonpath='{.metadata.resourceVersion}'

# See which managers are writing the object (server-side apply fields)
kubectl get deployment checkout -o jsonpath='{.metadata.managedFields[*].manager}'

# Watch how often the object changes (high churn = frequent conflicts)
kubectl get deployment checkout -w

# Inspect controllers that might be co-writing it
kubectl get hpa -A | grep checkout
kubectl describe deployment checkout | grep -A4 Events

# Look for an operator reconciling the same object
kubectl get events -n <ns> --field-selector involvedObject.name=checkout

The managedFields list reveals every manager touching the object — multiple managers on the same fields is the classic conflict source.

Step-by-Step Resolution

1. Just retry. Conflict is transient. Re-running the command re-reads the latest object and re-applies your change:

kubectl edit deployment checkout

For a single human edit, a second attempt almost always succeeds.

2. Prefer apply or patch over edit for targeted changes. A strategic-merge or JSON patch changes only your field and lets the server merge against the latest version, shrinking the collision window:

kubectl patch deployment checkout --type=merge -p '{"spec":{"replicas":4}}'

3. Use server-side apply for shared objects. Server-side apply tracks field ownership, so two managers editing different fields no longer conflict:

kubectl apply --server-side -f checkout.yaml

4. Fix read-modify-write loops in code. If your client or controller hits Conflict repeatedly, ensure it re-GETs the object (refreshing resourceVersion) before each retry, ideally with exponential backoff. Never reuse a cached resourceVersion after a failed write.

5. Resolve two-controller fights. If managedFields shows two managers writing the same field in a loop, you have a reconciliation conflict. Decide which controller owns the field and stop the other from writing it (disable the duplicate operator or scope its fields).

6. Avoid editing high-churn status. Do not hand-edit objects whose status is updated constantly (ResourceQuota, Endpoints, leases). Edit the controlling spec instead and let the controller reconcile status.

Prevention and Best Practices

  • Use kubectl patch or kubectl apply for scripted changes instead of edit, which holds a stale copy for as long as the editor is open.
  • Adopt server-side apply (--server-side) for objects edited by multiple actors; field-level ownership prevents most conflicts.
  • In custom controllers, always re-read the object before retrying a failed update, and use a controller-runtime client that handles conflict backoff for you.
  • Keep kubectl edit sessions short; the longer the editor is open, the wider the collision window on busy objects.
  • Make automation idempotent and retry-safe: treat Conflict as “retry after refresh,” not as a fatal error.
  • Avoid manually editing controller-managed status subresources. More patterns in the Kubernetes & Helm guides.

Frequently Asked Questions

Is Conflict a bug I need to fix, or just retry? For a one-off edit, retry — it is the expected behavior of optimistic concurrency. It only signals a real problem when it happens repeatedly on the same object, which points to two controllers fighting or a stale-version retry loop in code.

What is resourceVersion and why does it cause this? It is an opaque token that advances on every write. The server uses it to detect that the object changed between your read and your write. If your submitted version is older than what is stored, it returns Conflict to avoid overwriting the newer change.

Why does kubectl edit conflict but kubectl patch does not? edit reads the whole object, waits for your editor, then PUTs the entire (now stale) copy back. patch sends only the changed field and is merged server-side against the latest version, so it rarely collides.

My controller is stuck in a conflict loop. What is wrong? It is almost certainly reusing a cached resourceVersion after a failed update, or a second controller is writing the same field. Re-GET before each retry, and check managedFields for a competing manager.

Does server-side apply eliminate conflicts entirely? No, but it greatly reduces them by tracking field ownership: two managers editing different fields no longer conflict. Conflicts remain only when two managers claim the same field, which surfaces as a deliberate field-manager conflict you must resolve.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.