Skip to content
Latchkey

kubectl "data: Forbidden: field is immutable" - Fix Immutable ConfigMap/Secret in CI

A ConfigMap or Secret created with immutable: true cannot have its data/binaryData changed. Immutability protects running pods from accidental config drift, so any in-place update is rejected - you must recreate it.

What this error means

kubectl apply to an immutable ConfigMap/Secret fails with The ConfigMap "x" is invalid: data: Forbidden: field is immutable when immutable is set. The first create succeeded; the update is blocked.

kubectl output
The ConfigMap "app-config" is invalid: data: Forbidden: field is immutable when
`immutable` is set

Diagnose it: read events, not just status

A deployment that never becomes ready has the reason in its events and in the pod state, not in the deployment status. Read both before changing the manifest.

Terminal
kubectl rollout status deploy/<name> --timeout=120s
kubectl describe deploy/<name> | sed -n "/Events/,$p"
kubectl get pods -l app=<name> -o wide
kubectl describe pod <pod> | sed -n "/Events/,$p"
kubectl logs <pod> --previous --tail=50   # the crash before the restart

Common causes

Object marked immutable: true

Setting immutable: true locks data/binaryData. Any apply that changes a value (or the immutable flag) is rejected by the API server.

Updating in place instead of versioning

Immutable config is meant to be rolled by creating a new, differently-named object and pointing workloads at it - editing the existing one is not allowed.

How to fix it

Recreate the object to change it

For a one-off change, delete and re-create. Pods referencing it by name pick up the new data on their next start.

Terminal
kubectl delete configmap app-config
kubectl apply -f app-config.yaml

Use versioned names for immutable config

  1. Name immutable config with a content hash/version suffix (e.g. app-config-v2).
  2. Update the workload to reference the new name, triggering a rollout.
  3. Garbage-collect old versions once no pod references them.

How to prevent it

  • Treat immutable ConfigMaps/Secrets as versioned artifacts, not editable objects.
  • Use a hashed/versioned name so each change is a new object and a clean rollout.
  • Only set immutable: true when you intend the recreate-to-change workflow.

Frequently asked questions

What causes kubectl "data: Forbidden: field is immutable"?
There are 2 common causes: object marked immutable: true and updating in place instead of versioning. Setting immutable: true locks data/binaryData.
How do I fix kubectl "data: Forbidden: field is immutable"?
There are 2 fixes depending on which cause you have: recreate the object to change it and use versioned names for immutable config. Work through them in order, since the first is the most common.
What does kubectl "data: Forbidden: field is immutable" actually mean?
kubectl apply to an immutable ConfigMap/Secret fails with The ConfigMap "x" is invalid: data: Forbidden: field is immutable when immutable is set.
How do I stop kubectl "data: Forbidden: field is immutable" happening again?
Treat immutable ConfigMaps/Secrets as versioned artifacts, not editable objects. 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