selector does not match template labels: The controller's selector and its pod template disagree
A Deployment, ReplicaSet, or StatefulSet is rejected at creation if its selector does not match the labels on the pods it would create. The controller would never recognise its own pods.
Applies to: All Kubernetes versions
What it means
A controller finds the pods it owns by matching its spec.selector against pod labels. If the pod template's labels do not satisfy the selector, the controller would create pods and immediately fail to see them, then create more, forever. Kubernetes prevents this at validation time and rejects the object with selector does not match template labels. A related and harsher rule applies afterwards: a Deployment's selector is immutable once created. Changing it requires deleting and recreating the object, which is a real operational constraint rather than a formality — it means the labelling scheme has to be right the first time.
Most common causes
- A label added to the selector but not to the pod template, or the reverse.
- A typo in either the selector or the template labels.
- An attempt to change a Deployment's selector, which is immutable.
- A templating tool applying labels inconsistently to the two places.
- Copying a manifest and changing the app name in only one of the two locations.
- A mutating webhook adding labels to the template but not to the selector, or vice versa.
How to diagnose it
- Compare the two directly:
kubectl get deployment DEPLOY -o jsonpath='{.spec.selector.matchLabels}{"\n"}{.spec.template.metadata.labels}'. - Read the rejection message, which names the mismatch.
- For templated manifests, render locally and inspect both blocks in the output.
- Check whether an existing object's selector is being changed, which is a different error and needs a different fix.
How to fix it
- Make the template's labels a superset of the selector. Extra labels on the template are fine; missing ones are not.
- To change a selector on an existing Deployment, create a new Deployment with the new selector and remove the old one. There is no in-place edit.
- Define labels once in a templating tool and reference them in both places, so they cannot drift.
- Keep selectors minimal — one or two stable labels — so that adding descriptive labels later does not require a recreate.
Notes
Selector immutability is the reason to keep selectors small and stable. A selector containing a version label seems tidy until the first version change requires deleting and recreating the Deployment, with the downtime that implies.
Related
- Service has no endpoints — No ready pods behind the Service
- error validating data — The manifest does not match the schema
Sources
- Kubernetes documentation — Deployments: selector
- Kubernetes documentation — Labels and Selectors
- Kubernetes documentation — ReplicaSet