Fix Kubernetes CreateContainerConfigError

Quick answer
CreateContainerConfigError means the kubelet can't build your container's config because it references a ConfigMap or Secret that's missing, misnamed, or missing a key. Here's how to find the exact reference that's broken and fix it.
- What this error means
- Step 1: See the actual error
- Cause 1: The referenced ConfigMap or Secret does not exist
- Cause 2: The key doesn't exist in the ConfigMap or Secret
- Cause 3: The ConfigMap or Secret is in a different namespace
8 min read · Kubernetes
Fix Kubernetes CreateContainerConfigError
You run kubectl get pods and see this:
NAME READY STATUS RESTARTS AGE
api-7d9f8b 0/1 CreateContainerConfigError 0 40s
CreateContainerConfigError means the kubelet tried to build the container's configuration and couldn't — because the pod references a ConfigMap or Secret that doesn't exist, is misnamed, lives in the wrong namespace, or is missing a key you asked for. The container never starts, so there are no logs to read. Everything you need is in the pod's Events.
This is not the same as your app crashing. The failure happens before the container process ever runs.
What this error means
When you inject config with env.valueFrom.configMapKeyRef, secretKeyRef, or bulk-load with envFrom, the kubelet resolves every one of those references while assembling the container config. If any reference can't be resolved, it stops and marks the pod CreateContainerConfigError. Restart count stays at 0 because the container was never created — there's nothing to restart, only retry.
Compare this to its neighbors so you diagnose the right thing:
- CreateContainerConfigError — config assembly failed (missing/invalid ConfigMap or Secret). Covered here.
- CrashLoopBackOff — the container did start, then the app exited. Different problem — see Fix Kubernetes CrashLoopBackOff.
- CreateContainerError / RunContainerError — the container runtime failed to create or start the process (bad command, missing mount, image entrypoint issue) — a runtime problem, not a config-resolution one.
Step 1: See the actual error
The status is a category. The Events tell you the exact reference that's broken.
kubectl describe pod <pod-name>Scroll to the Events section at the bottom. You'll see one of these messages:
Warning Failed kubelet Error: configmap "app-config" not found
Warning Failed kubelet Error: secret "db-credentials" not found
Warning Failed kubelet Error: couldn't find key DATABASE_URL in ConfigMap default/app-config
Read that message literally — it names the object and, when relevant, the key. That single line points you at exactly one of the causes below.
Cause 1: The referenced ConfigMap or Secret does not exist
The most common cause. Your pod references app-config, but no such object exists — often a typo, or the ConfigMap was never applied, or it was deleted.
What you'll see:
Error: configmap "app-config" not found
Broken pod spec:
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config # ← this ConfigMap doesn't exist
key: LOG_LEVELFix. Confirm whether the object exists in the pod's namespace:
kubectl get configmap app-config -n <namespace>
kubectl get secret db-credentials -n <namespace>If it's genuinely missing, create it:
kubectl create configmap app-config \
--from-literal=LOG_LEVEL=info \
-n <namespace>If it exists under a slightly different name, fix the name: field in the pod spec to match exactly. Names are case-sensitive and must be exact.
Cause 2: The key doesn't exist in the ConfigMap or Secret
The object exists, but the specific key you referenced isn't in it. This happens when you rename a key in the ConfigMap but forget to update the pod spec, or misspell it.
What you'll see:
Error: couldn't find key DATABASE_URL in ConfigMap default/app-config
Broken reference:
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: DATABASE_URL # ← key not present in app-configFix. List the keys that actually exist in the object:
kubectl get configmap app-config -n <namespace> -o jsonpath='{.data}' | jq
# For secrets, keys live under .data (values are base64):
kubectl get secret db-credentials -n <namespace> -o jsonpath='{.data}' | jq 'keys'Then either correct the key: in the pod spec, or add the missing key to the object:
kubectl patch configmap app-config -n <namespace> \
--type merge -p '{"data":{"DATABASE_URL":"postgres://db:5432/app"}}'Stuck on this in production?
We debug exactly this kind of issue for platform teams — usually in a single working session.
Cause 3: The ConfigMap or Secret is in a different namespace
ConfigMaps and Secrets are namespaced. A pod can only reference objects in its own namespace — there is no cross-namespace reference for env or volumes. If your ConfigMap lives in default but the pod runs in staging, the kubelet reports it as "not found" even though it clearly exists somewhere.
What you'll see — the same "not found" message as Cause 1, which is why people chase the wrong fix:
Error: configmap "app-config" not found
Fix. Check where the object actually lives versus where the pod runs:
kubectl get configmap app-config --all-namespaces
kubectl get pod <pod-name> -o jsonpath='{.metadata.namespace}'If they don't match, create the ConfigMap in the pod's namespace. Copy it across if needed:
kubectl get configmap app-config -n default -o yaml \
| sed 's/namespace: default/namespace: staging/' \
| kubectl apply -n staging -f -Cause 4: A required envFrom reference is missing
envFrom bulk-loads every key from a ConfigMap or Secret as environment variables. By default the reference is required — if the object is missing, the whole pod fails with CreateContainerConfigError, exactly like a single keyRef.
Broken spec:
envFrom:
- configMapRef:
name: shared-config # missing → CreateContainerConfigError
- secretRef:
name: shared-secretsFix — option A: create the missing object (see Cause 1).
Fix — option B: if the config is genuinely optional, mark it so. With optional: true, the kubelet skips a missing reference instead of failing:
envFrom:
- configMapRef:
name: shared-config
optional: true # skip silently if absentUse optional: true deliberately — it's the right call for feature-flag overlays, but hiding a genuinely required config behind it just trades a loud failure for a silent misconfiguration at runtime.
Cause 5: Prevent it in the first place
Most CreateContainerConfigErrors are name and key drift between manifests. Kill the drift at the source:
- Template config with the workload. Manage ConfigMaps/Secrets and Deployments together in the same Helm chart or Kustomize base so names stay in lockstep. Kustomize's
configMapGeneratorappends a content hash to the name and rewrites references for you, which also forces a rollout on change. - Validate before apply. Run
kubectl apply --dry-run=server -f .in CI to catch missing objects against the live cluster, andhelm template | kubeconformto catch schema issues. - Order your applies. Apply ConfigMaps and Secrets before the Deployments that consume them, or apply the whole directory at once so ordering doesn't matter.
Quick reference
1# The one command that tells you the exact broken reference
2kubectl describe pod <name> # read the Events section
3
4# Verify the object and its keys exist in the pod's namespace
5kubectl get configmap <name> -n <ns>
6kubectl get secret <name> -n <ns> -o jsonpath='{.data}' | jq 'keys'
7
8# Find an object that's in the wrong namespace
9kubectl get configmap <name> --all-namespaces| Event message | Cause | Fix |
|---|---|---|
configmap "X" not found | Missing or misnamed object | Create it, or fix name: |
secret "X" not found | Missing or misnamed Secret | Create it, or fix name: |
couldn't find key Y in ConfigMap Z | Key not present | Fix key: or add the key |
not found but object exists elsewhere | Wrong namespace | Create it in the pod's namespace |
Frequently Asked Questions
What is the difference between CreateContainerConfigError and CrashLoopBackOff?
CreateContainerConfigError happens before the container starts — the kubelet couldn't assemble the config from a ConfigMap or Secret, so no process ever ran. CrashLoopBackOff means the container did start and then the app exited, so you have logs to read. See Fix Kubernetes CrashLoopBackOff.
Why does my pod show CreateContainerConfigError with 0 restarts?
Because the container was never created. Restarts only count actual container terminations. The kubelet keeps retrying config assembly, but since no process ran there's nothing to restart — the counter stays at 0.
How do I find which ConfigMap or Secret is causing the error?
Run kubectl describe pod <name> and read the Events section. The kubelet prints the exact object name and, for a missing key, the key name too — for example couldn't find key DATABASE_URL in ConfigMap default/app-config.
Can a pod reference a ConfigMap in a different namespace?
No. ConfigMaps and Secrets are namespaced and can only be referenced by pods in the same namespace. If the object lives elsewhere, the kubelet reports "not found." Create a copy in the pod's namespace.
How do I make a missing ConfigMap not fail the pod?
Set optional: true on the configMapRef/secretRef in envFrom, or on the individual configMapKeyRef/secretKeyRef. The kubelet then skips the missing reference instead of failing. Use it only when the config is genuinely optional.
See also
- Fix Kubernetes CrashLoopBackOff — when the container starts but the app keeps crashing
- ConfigMaps and Secrets: Managing Configuration in Kubernetes — how to structure and inject config cleanly
- The Kubernetes Debugging Guide — a systematic workflow for any stuck pod
Fighting recurring config drift across environments? Talk to us at Coding Protocols — we build GitOps pipelines that keep your ConfigMaps, Secrets, and workloads in sync so these errors never reach production.
Official References
- Debug Pods — reading pod status, events and container states
- kubectl reference — command syntax, output formats and selectors
Was this article helpful?
Be the first to rate this article
Related Topics
Found this useful? Share it.


