Kubernetes troubleshooting

CreateContainerConfigError: Causes and How to Fix

CreateContainerConfigError means the kubelet could not build the configuration for a container, so the container never started. The cause is almost always a Secret or ConfigMap the pod refers to that is missing or lacks the key, or a security setting the image cannot satisfy. The event message names which one.

By , Founder at SeaGit

·

Key takeaways

  • The container never starts, so the restart count stays at zero. The fault is in the pod spec or the objects it references, not in your application code.
  • Read the event message first. It names the missing Secret or ConfigMap, or the missing key inside it.
  • Secret and ConfigMap references are resolved in the pod namespace only. A Secret in another namespace is invisible to the pod.
  • Set optional: true only on references your app can run without. It hides the problem rather than fixing it.

Read the event first

Describe the pod and read the Events section at the bottom. The reason appears in the container state, and the message says what the kubelet could not find.

bash
kubectl describe pod my-api-6d8f9 -n prod | sed -n '/Containers:/,/Conditions:/p'

kubectl describe pod my-api-6d8f9 -n prod | sed -n '/Events:/,$p'

# Just the waiting reason and message for each container
kubectl get pod my-api-6d8f9 -n prod \
  -o jsonpath='{range .status.containerStatuses[*]}{.name}{": "}{.state.waiting.reason}{" "}{.state.waiting.message}{"\n"}{end}'
The container state block, the events, and the waiting reason in one line per container.

The message decides the cause. Match the text to one of the three sections below. The lines are illustrative; copy the exact text from your own events.

text
# Secret referenced by env or envFrom does not exist
Error: secret "db-credentials" not found

# ConfigMap referenced by env or envFrom does not exist
Error: configmap "app-settings" not found

# Object exists but the key inside it does not
Error: couldn't find key DB_PASSWORD in Secret prod/db-credentials

# Security context the image cannot satisfy
container has runAsNonRoot and image has non-numeric user (app), cannot verify user is non-root
Common CreateContainerConfigError messages and the cause each one points to.

Cause 1: the Secret or ConfigMap does not exist

A pod reads environment variables from a Secret or ConfigMap with secretKeyRef, configMapKeyRef or envFrom. The reference names an object and a namespace. The object must exist in that namespace before the pod starts. Check the object from the pod namespace:

bash
# Every object the pod names, by kind
kubectl get pod my-api-6d8f9 -n prod -o json \
  | jq -r '.spec.containers[] | (.envFrom[]? | (.secretRef.name // .configMapRef.name // empty)), (.env[]? | (.valueFrom.secretKeyRef.name // .valueFrom.configMapKeyRef.name // empty))' \
  | sort -u

# Check each one exists in the same namespace
kubectl get secret db-credentials -n prod
kubectl get configmap app-settings -n prod
List the referenced objects, then confirm each one exists in the pod's own namespace.

The usual mistakes are a Secret created in the default namespace, a name with a different suffix from the chart release, and a Secret that a GitOps sync has not applied yet. Create the object in the same namespace, or correct the reference.

Cause 2: the object exists but the key does not

When a Secret or ConfigMap exists but a key named in a secretKeyRef or configMapKeyRef is not in its data, the kubelet cannot build the environment and reports CreateContainerConfigError. Compare the keys the pod expects with the keys the object holds. Secret data is base64 in the API, so read the key names, not the values:

bash
# Key names only, values are not printed
kubectl get secret db-credentials -n prod -o jsonpath='{.data}' | jq 'keys'

kubectl get configmap app-settings -n prod -o jsonpath='{.data}' | jq 'keys'

# The key the pod asks for
kubectl get pod my-api-6d8f9 -n prod -o jsonpath='{.spec.containers[0].env[*].valueFrom.secretKeyRef.key}'
Compare the key names. A case difference such as DB_Password and DB_PASSWORD is enough to fail.

Fix it by adding the key or correcting the reference

Add the missing key to the object, or change the reference to the key that exists. If the value is optional for your app, mark that single reference optional: true so the pod starts without it, and make sure the app handles the absence.

yaml
env:
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-credentials
        key: password
        optional: false   # the default: the pod fails if the key is missing
A required reference. Leave optional unset unless the app can run without the value.

Cause 3: the image user conflicts with runAsNonRoot

If the pod sets runAsNonRoot: true and the image sets its user by name rather than by number, the kubelet cannot prove the user is not root and refuses to start the container. The message reads "image has non-numeric user". This is the cause to check when no Secret or ConfigMap is missing.

yaml
securityContext:
  runAsNonRoot: true
  runAsUser: 10001   # a numeric UID, so the kubelet can verify it
  runAsGroup: 10001
Set a numeric user in the pod or container securityContext, or change the image to use a numeric USER.

The kubernetes.io security-context page describes runAsNonRoot and runAsUser. Check the image metadata with docker image inspect or your registry UI before you pick a UID, because the UID must match the files the app writes.

Verify the fix

After you fix the object or the spec, the kubelet retries the container. Watch the pod leave the waiting state and confirm the container is running:

bash
kubectl get pod my-api-6d8f9 -n prod -w

kubectl get pod my-api-6d8f9 -n prod \
  -o jsonpath='{.status.containerStatuses[0].ready}{" "}{.status.containerStatuses[0].state}{"\n"}'
A ready container shows true and a running state. If the pod was recreated, use the new pod name.

If the pod is managed by a Deployment and the spec did not change, the ReplicaSet may keep the old pod. Delete the stuck pod, or roll the Deployment with a new annotation so a fresh pod starts.

Frequently asked questions

CreateContainerConfigError: Causes and How to Fix: FAQ

Is CreateContainerConfigError the same as CrashLoopBackOff?

No. CrashLoopBackOff means the container started and then exited again and again. CreateContainerConfigError means the container never started because its configuration could not be built, so the restart count does not climb.

Why does a Secret I can see in the console not work for the pod?

The pod reads only Secrets in its own namespace. A Secret in a different namespace, or the same name with a different suffix from a Helm release, is a different object.

Should I mark every reference optional to stop the error?

Only the references your app can run without. Optional references hide a missing value, and the app then fails later with a less clear error.

How do I check a Secret value without printing it?

Read the key names with jq keys, as shown above, or check that the key exists in the object. Avoid printing the data field in a shared terminal or a log.

Sources

Checked 10 October 2026.

  1. Kubernetes: Secrets — Secrets consumed as environment variables and as mounted volumes, and the secretKeyRef pattern.
  2. Kubernetes: ConfigMaps — ConfigMap keys consumed as environment variables and the namespace rule.
  3. Kubernetes: Configure a Security Context for a Pod or Container — runAsUser, runAsGroup and runAsNonRoot.
  4. Kubernetes: Debug Running Pods — Using kubectl describe and the pod events to find why a container will not start.

Read next