Kubernetes CreateContainerConfigError: a missing Secret or ConfigMap, and how to find it
Fix Kubernetes CreateContainerConfigError: kubectl describe names the missing Secret, ConfigMap or key. Check the namespace and the key, then let the pod restart.
by OhSudo ··
Checked on real software: Kubernetes (kind) · November 2026How we check
Not sure this is your cause?Find it step by step: Pod not running →
Part of a learning path:Kubernetes: debugging pods
$ kubectl get podsNAME READY STATUS RESTARTS AGEmyapp-7d9f8b6c4-x2k9p 0/1 CreateContainerConfigError 0 45sThe image was pulled, and the container hasn’t started. Kubernetes can’t prepare its configuration, and that nearly always means an environment variable points to a Secret or ConfigMap that isn’t there. Since the application never ran, kubectl logs is empty, so look elsewhere.
- Podenv from a Secret or ConfigMaprefers to(fails)
- Secret or ConfigMapmissing, or no such key(breaks here)so
- Containernever created, no logs
TL;DR
The events name the missing thing. Create it, or fix the name. The kubelet keeps retrying, so the pod usually starts by itself.
1. Read the events
At the bottom, under Events:
Warning Failed 12s (x4 over 45s) kubelet Error: secret "db-credentials" not found| The event says | Means |
|---|---|
secret "x" not found |
No Secret by that name in this namespace |
configmap "x" not found |
The same, for a ConfigMap |
couldn't find key password in Secret default/x |
The Secret exists, without that key |
couldn't find key x in ConfigMap default/y |
The same, for a ConfigMap |
container has runAsNonRoot and image will run as root |
Not about config: see that article |
failed to sync secret cache |
Often temporary, or the pod’s service account can’t read it |
2. A missing Secret or ConfigMap
See what the pod asks for:
kubectl get pod myapp-7d9f8b6c4-x2k9p -o jsonpath='{.spec.containers[*].envFrom}'kubectl get pod myapp-7d9f8b6c4-x2k9p -o yaml | grep -A4 -E 'secretKeyRef|configMapKeyRef|secretRef|configMapRef'And compare it with what exists:
Then create it, or fix the name in the Deployment. The value goes on the command line here only as an example, and from a file is better:
kubectl create secret generic db-credentials \ --from-literal=username=app \ --from-file=password=./password.txtIs it in another namespace? Secrets and ConfigMaps can only be used from their own namespace. That’s a common reason for this error when moving between environments:
kubectl get secrets -A | grep db-credentialskubectl config view --minify --output 'jsonpath={..namespace}'Copy it across, or better, create it from your source of truth.
Is it created by something else? A chart or an operator like External Secrets may be slow or failing. Look at that one’s status. With Helm, a Secret from another release may be installed later, or under a different name:
kubectl get externalsecrethelm list3. A wrong key
The Secret is there, and it has other keys:
Error: couldn't find key password in Secret default/db-credentialsList the keys, without showing the values:
kubectl get secret db-credentials -o jsonpath='{.data}' | python3 -c 'import json,sys; print(list(json.load(sys.stdin)))'kubectl describe secret db-credentialsThe usual reason is a tiny difference such as DB_PASSWORD vs db-password. Keys are case-sensitive. Fix one to match:
env: - name: DB_PASSWORD valueFrom: secretKeyRef: name: db-credentials key: passwordThe Kubernetes Manifest Generator writes the Secret, the ConfigMap and the references so that they match.
4. If it’s truly optional
For a setting your application can do without, say so, and the pod starts without it:
env: - name: FEATURE_FLAG valueFrom: configMapKeyRef: name: features key: flag optional: trueenvFrom: - secretRef: name: extra-settings optional: trueDon’t use it for what’s really required, like a database password. Then the application starts, and fails later in a way that’s harder to diagnose.
5. After you fix it
The kubelet retries, so the pod usually starts on its own, within a minute or so. Want it faster?
kubectl delete pod myapp-7d9f8b6c4-x2k9pkubectl rollout restart deployment/myappkubectl rollout status deployment/myappIf you changed the Deployment itself, a new ReplicaSet rolls out without any of that. And remember that a running pod doesn’t pick up a changed environment variable until it restarts.
If there’s now a different failure, the application itself is running: read kubectl logs, and see CrashLoopBackOff.
6. Keep it from happening
Create what’s referenced before the Deployment, and apply both together. With one file, the order is yours to control:
kubectl apply -f secret.yaml -f deployment.yamlTest against the cluster first, as a dry run on the server side checks a lot, even though it doesn’t check for references:
kubectl apply --dry-run=server -f deployment.yamlDon’t commit real Secrets in plain YAML, since Base64 isn’t encryption. Use your secret manager with External Secrets, or Sealed Secrets. And in a pipeline, set the value from your CI’s secret store.
Warning
Avoid pasting the password into the Deployment as a plain value: to get past this error. It then sits in git, in kubectl describe and in your cluster’s history. Fix the reference instead.
Shell, we have a problem!
Similar, but different: CreateContainerError is a failure a step later, often from a bad command or a name clash. ImagePullBackOff means the image can’t be fetched. CrashLoopBackOff means the application started and exited. Pending means no node is available. A Secret mounted as a volume gives MountVolume.SetUp failed … secret "x" not found, with the status ContainerCreating. For the commands around this, see the kubectl Cheat Sheet.
$ ./practice.sh
Practice this in the terminal
Open the Terminal Playground with this article’s scenario loaded. It is safe and runs in your browser.
Found this useful? Share it.
Found a mistake? Let us know at contact@ohsudo.com.