Skip to content
Latchkey

Helm "UPGRADE FAILED: cannot patch ... field is immutable"

Helm upgrades by patching existing objects. When a chart change touches an immutable field - a Deployment selector, a Job template, a Service clusterIP - the API server rejects the patch, and Helm reports cannot patch ... field is immutable.

What this error means

helm upgrade fails with Error: UPGRADE FAILED: cannot patch "<name>" with kind <Kind>: <Kind> "<name>" is invalid: spec.<field>: Invalid value: ...: field is immutable.

helm output
Error: UPGRADE FAILED: cannot patch "api" with kind Deployment:
Deployment.apps "api" is invalid: spec.selector: Invalid value: ...:
field is immutable

Diagnose it: render the chart before you install it

Most Helm failures are visible in the rendered manifests. Template them locally with the same values CI uses and you will usually see the problem without touching the cluster.

Terminal
# what will actually be applied
helm template <release> <chart> -f values.ci.yaml | head -60

# validate against the live cluster schema without installing
helm install <release> <chart> -f values.ci.yaml --dry-run --debug

# what state is the release actually in?
helm history <release>
helm status <release>

Common causes

Chart changed an immutable selector/template

Editing spec.selector.matchLabels (Deployment/StatefulSet) or a Job’s spec.template in the chart produces a patch the API server forbids on the existing object.

Service clusterIP or other locked field changed

A change to Service.spec.clusterIP or another field fixed at creation cannot be patched in place during the upgrade.

How to fix it

Recreate the object instead of patching it

For immutable fields, delete the conflicting resource so the next Helm upgrade re-creates it with the new spec.

Terminal
kubectl delete deployment api -n <ns>
helm upgrade --install api ./chart -n <ns>

Keep immutable fields stable in the chart

  1. Never change spec.selector labels on an existing Deployment/StatefulSet via the chart.
  2. For Jobs, render a new name (e.g. include a hash) so each run is a new object.
  3. Diff before upgrading: helm diff upgrade (helm-diff plugin) to catch immutable changes.

How to prevent it

  • Decide selector labels once and keep them constant across chart versions.
  • Use helm diff upgrade in CI to catch immutable-field changes before they fail.
  • Recreate (blue/green) rather than mutate when an immutable field must change.

Frequently asked questions

What causes Helm "UPGRADE FAILED: cannot patch ... field is immutable"?
There are 2 common causes: chart changed an immutable selector/template and service clusterip or other locked field changed. Editing spec.selector.matchLabels (Deployment/StatefulSet) or a Job’s spec.template in the chart produces a patch the API server forbids on the existing object.
How do I fix Helm "UPGRADE FAILED: cannot patch ... field is immutable"?
There are 2 fixes depending on which cause you have: recreate the object instead of patching it and keep immutable fields stable in the chart. Work through them in order, since the first is the most common.
What does Helm "UPGRADE FAILED: cannot patch ... field is immutable" actually mean?
helm upgrade fails with Error: UPGRADE FAILED: cannot patch "<name>" with kind <Kind>: <Kind> "<name>" is invalid: spec.<field>: Invalid value: ...: field is immutable.
How do I stop Helm "UPGRADE FAILED: cannot patch ... field is immutable" happening again?
Decide selector labels once and keep them constant across chart versions. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card