kubectl apply Field Manager Conflict Error: How to Fix It (2026)
How to resolve Kubernetes field manager conflict errors when using server-side apply — what causes them, how to identify the conflicting manager, and three different ways to fix it cleanly.
If you have migrated to server-side apply or are using tools like ArgoCD, Helm, and kubectl alongside each other, you have probably hit this error at some point:
Apply failed with 1 conflict: conflict with "helm" using apps/v1:
.spec.replicas
Or the longer form:
error: Apply failed with 2 conflicts:
conflicts with "kubectl" using /v1:
- .metadata.annotations.kubectl.kubernetes.io/last-applied-configuration
conflicts with "helm" using apps/v1:
- .spec.template.spec.containers[name="api"].image
These are field manager conflicts — a feature of server-side apply that prevents two different tools from accidentally overwriting each other's changes. Understanding the mechanism makes the fix straightforward.
What Server-Side Apply and Field Managers Are
Traditional kubectl apply (client-side apply) works by storing the last applied configuration in an annotation and doing a three-way merge locally in kubectl. It has no concept of ownership — whoever applies last wins.
Server-side apply (introduced in Kubernetes 1.18, stable in 1.22) moves this logic to the API server. The API server tracks which "field manager" owns each field in a resource. When you apply a change to a field owned by a different manager, Kubernetes returns a conflict error instead of silently overwriting.
This is protection, not a bug. But when you have multiple tools managing the same resource (ArgoCD + Helm, or kubectl + ArgoCD), you need to resolve the ownership question explicitly.
Diagnosing the Conflict
# See the managed fields on a resource
kubectl get deployment my-app -o json | jq '.metadata.managedFields'Output shows each manager, the fields they own, and when they last touched the resource:
[
{
"manager": "helm",
"operation": "Apply",
"apiVersion": "apps/v1",
"time": "2026-07-01T10:00:00Z",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:spec": {
"f:replicas": {},
"f:template": {
"f:spec": {
"f:containers": {
"k:{\"name\":\"api\"}": {
"f:image": {}
}
}
}
}
}
}
},
{
"manager": "kubectl",
"operation": "Apply",
"apiVersion": "apps/v1",
"time": "2026-07-05T14:00:00Z",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:spec": {
"f:replicas": {}
}
}
}
]Here you can see both helm and kubectl claim ownership of spec.replicas — that is the conflict.
Fix Option 1: Force Apply (Override the Conflict)
The simplest resolution — tell Kubernetes that your apply should win and take ownership from the previous manager:
kubectl apply --server-side --force-conflicts -f deployment.yamlThis removes the ownership from the conflicting manager and assigns it to your current apply. Use this when:
- The previous manager no longer exists or manages this resource
- You are migrating from one tool to another (Helm → kubectl, or kubectl → ArgoCD)
- You are the authoritative source and the conflict is from an old/stale manager
ArgoCD example — if ArgoCD is managing the resource but you need to apply a manual fix:
kubectl apply --server-side --force-conflicts -f deployment.yaml --field-manager=argocd-application-controllerFix Option 2: Remove the Conflicting Manager
If the other manager is no longer active (you stopped using Helm but its manager entry remains), clean it up:
# Remove all managed fields from a specific manager
kubectl patch deployment my-app \
--type=json \
-p='[{"op": "remove", "path": "/metadata/managedFields/0"}]'The index 0 is the position in the managedFields array. Check kubectl get deployment my-app -o json | jq '.metadata.managedFields | keys' to find the right index.
A cleaner approach for full cleanup:
# Replace managedFields with just your manager
kubectl apply --server-side --force-conflicts \
--field-manager=kubectl \
-f deployment.yamlThis forces kubectl to take ownership of all fields in the manifest.
Fix Option 3: Use a Consistent Field Manager Name
The conflict often happens because different invocations use different manager names (kubectl vs kubectl-xxx vs argocd vs helm). If you are using ArgoCD + kubectl together, standardize:
# Always use the same manager name when applying alongside ArgoCD
kubectl apply --server-side \
--field-manager=kubectl \
-f deployment.yamlOr configure ArgoCD to use server-side apply with a specific manager:
# ArgoCD Application spec
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
syncPolicy:
syncOptions:
- ServerSideApply=trueFix Option 4: Convert Back to Client-Side Apply
If server-side apply is causing too many issues and you do not need its benefits, revert a resource to client-side apply:
# Remove all managedFields (converts back to client-side)
kubectl patch deployment my-app \
--type=merge \
-p '{"metadata":{"managedFields":null}}'
# Then apply normally without --server-side
kubectl apply -f deployment.yamlAvoiding Conflicts in CI/CD
If you use both Helm and kubectl apply in your pipelines, separate their concerns:
# Option A: Always use --server-side with --force-conflicts in CI
kubectl apply --server-side --force-conflicts -f manifests/
# Option B: Use kubectl only for resources not managed by Helm/ArgoCD
# and let Helm/ArgoCD own everything else
# Option C: Migrate entirely to GitOps with ArgoCD — one tool owns all resourcesThe best long-term solution is single-tool ownership per resource. Having Helm manage the Deployment and kubectl patch it ad-hoc is the root cause of most field manager conflicts in practice.
More kubectl troubleshooting? Read our kubectl exec permission denied fix and ArgoCD sync stuck unknown fix.
Today I Fixed
Short real fixes from production — posted daily
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
ArgoCD App of Apps Not Syncing — Every Fix (2026)
Your ArgoCD App of Apps pattern stopped syncing. Child apps aren't created, parent shows OutOfSync, or sync is stuck. Here are every cause and the exact fix.
ArgoCD Image Updater Not Syncing — Fix Guide
ArgoCD Image Updater detects a new image tag but doesn't update the Application. Here's how to diagnose and fix annotation errors, registry auth issues, write-back problems, and sync failures.
ArgoCD Resource Hook Failed: How to Debug and Fix It
ArgoCD PreSync or PostSync hooks failing silently? Here's how to find the real error, fix hook job issues, and stop your deployments from getting stuck.