1. Introduction
A pod that never leaves Init:0/1 is one of the most common — and most misdiagnosed — scheduling problems in production. The application container never starts, so there are no app logs to look at, and kubectl get pods just shows a status like Init:0/1, Init:1/2, or Init:CrashLoopBackOff that tells you an init container is the hold-up but not why.
Init containers run to completion, in order, before any app container starts. If one hangs or exits non-zero, the pod is stuck by design — Kubernetes will not proceed until every init container succeeds. This guide walks through reading the status correctly, pulling logs from the right container, and fixing the usual culprits: failing dependency checks, missing ConfigMaps/Secrets, volume permission problems, and image pull failures on the init image itself.
2. What "Init:0/1" Actually Means
The init status field is Init:M/N — M init containers have completed out of N total. So Init:0/1 means the first (and only) init container has not finished. Common variants:
Init:0/2— first of two init containers is still running or crashingInit:CrashLoopBackOff— an init container exited non-zero and is being restarted with backoffInit:Error— an init container exited non-zero on its last attemptInit:ImagePullBackOff— the init container's image can't be pulled (separate from the app image)
The key mental model: the pod is behaving correctly. An init container is blocking startup on purpose, and your job is to find which one and why.
3. Common Causes
- A "wait-for-dependency" init container looping until a database, migration, or service is reachable — and that dependency never becomes ready
- The init container references a
ConfigMaporSecretthat doesn't exist in the namespace - The init container's image tag is wrong or the registry needs credentials — surfaces as
Init:ImagePullBackOff - A mounted volume (PVC) is not yet bound, leaving the init container stuck waiting to mount
- File permission mismatch: the init container writes to a volume as one UID, the app runs as another (
fsGroupnot set) - A script bug — the init command exits 1, causing
Init:CrashLoopBackOff - A missing
RBACpermission when the init container calls the Kubernetes API (e.g. a schema migration job that lists resources) - Network policy blocking the init container from reaching the dependency it is polling
4. Step-by-Step Diagnosis and Fix
Step 1: Read the pod status and identify the failing init container
# See the init status column
kubectl get pod <pod-name> -n <namespace>
# NAME READY STATUS RESTARTS AGE
# api-7d9f 0/1 Init:0/1 0 4m
# describe shows each init container and its state
kubectl describe pod <pod-name> -n <namespace>
# Look under "Init Containers:" for State: Waiting / Running / Terminated
# and the Reason (e.g. CrashLoopBackOff, ImagePullBackOff)
Step 2: Pull logs from the init container specifically
Plain kubectl logs targets the app container, which hasn't started — you must pass -c with the init container name.
# List init container names
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.initContainers[*].name}'; echo
# Logs from a specific init container
kubectl logs <pod-name> -n <namespace> -c <init-container-name>
# If it is crash-looping, get the PREVIOUS attempt's logs
kubectl logs <pod-name> -n <namespace> -c <init-container-name> --previous
Step 3: Handle the "waiting for a dependency" pattern
The most common init container is a poll loop like this. If it never exits, the dependency is genuinely unreachable — do not just delete the init container, fix the dependency.
initContainers:
- name: wait-for-db
image: busybox:1.35
command: ['sh', '-c', 'until nc -z postgres 5432; do echo waiting for db; sleep 2; done']
# Reproduce the exact check from a debug pod in the SAME namespace
kubectl run netcheck --image=busybox:1.35 -n <namespace> --rm -it --restart=Never -- \
sh -c 'nc -zv postgres 5432'
# Is the Service resolvable and does it have endpoints?
kubectl get endpoints postgres -n <namespace> # ENDPOINTS must not be <none>
Step 4: Fix missing ConfigMap / Secret references
# describe will show: Error: configmap "app-config" not found
kubectl describe pod <pod-name> -n <namespace> | grep -i -A2 'not found'
# Confirm what exists in the namespace
kubectl get configmap,secret -n <namespace>
# Names are case-sensitive and namespace-scoped — a Secret in the wrong
# namespace is invisible to the pod.
Step 5: Resolve Init:ImagePullBackOff on the init image
# The init container image is pulled just like any other image
kubectl describe pod <pod-name> -n <namespace> | grep -i -A3 'Failed'
# Verify the tag exists and creds are present
kubectl get pod <pod-name> -n <namespace> \
-o jsonpath='{.spec.initContainers[*].image}'; echo
kubectl get pod <pod-name> -n <namespace> \
-o jsonpath='{.spec.imagePullSecrets[*].name}'; echo
Step 6: Fix volume permission / mount waits
# If the init container writes to a volume the app later reads,
# a UID mismatch leaves files unreadable. Set fsGroup so the volume
# is group-owned and writable by both containers:
spec:
securityContext:
fsGroup: 2000
initContainers:
- name: fix-perms
image: busybox:1.35
command: ['sh', '-c', 'chown -R 2000:2000 /data']
volumeMounts:
- name: data
mountPath: /data
# If the pod is stuck mounting, the PVC may still be Pending:
kubectl get pvc -n <namespace>
5. Verification Steps
# Watch the pod transition out of Init and into Running
kubectl get pod <pod-name> -n <namespace> -w
# ...Init:0/1 -> PodInitializing -> Running
# Confirm all init containers terminated with exit code 0
kubectl get pod <pod-name> -n <namespace> \
-o jsonpath='{range .status.initContainerStatuses[*]}{.name}{"="}{.state.terminated.exitCode}{"\n"}{end}'
# App container is finally up
kubectl logs <pod-name> -n <namespace>
6. Common Mistakes
- Running
kubectl logswithout-c <init-name>and concluding "there are no logs" - Deleting or commenting out the init container to "unblock" the pod — this hides a real dependency or ordering problem
- Forgetting init containers run sequentially; a slow first init container delays everything after it
- Not using
--previouson a crash-looping init container, so you read an empty current attempt instead of the failure - Assuming a Secret/ConfigMap exists cluster-wide — they are namespaced
7. Prevention Tips
- Add timeouts to wait-for loops so a stuck dependency fails loudly instead of hanging forever
- Prefer
readinessProbegating and proper Service readiness over hand-rolled poll loops where possible - Validate that referenced ConfigMaps/Secrets exist in CI before applying manifests
- Set
fsGroupwhenever an init container and app container share a writable volume - If the init container pulls from a private registry, reuse the same image pull troubleshooting steps as the app image
- When a "wait" init container hangs, cross-check internal service communication — the dependency may be up but unreachable
8. FAQ
How do I see logs when the pod is stuck in Init and the app container never started?
Use kubectl logs <pod> -c <init-container-name>. Plain kubectl logs defaults to the app container, which hasn't started yet, so it returns nothing. For a crash-looping init container add --previous to read the failed attempt instead of the empty current one.
My init container is Init:CrashLoopBackOff. Is that different from the app crash-looping?
Yes. Init:CrashLoopBackOff means an init container is exiting non-zero and being retried with backoff — the app container has never run. Get the init container's --previous logs and check its exit code with kubectl get pod -o jsonpath on .status.initContainerStatuses. It is usually a script bug or a dependency check returning failure.
Can I just remove the init container to get the pod running?
You can, but you almost never should. Init containers exist to guarantee ordering — schema migrations completed, a dependency reachable, permissions fixed. Removing it typically moves the failure into the app container (which now starts before its dependency is ready). Fix the underlying dependency instead.
9. Summary
| Symptom | Cause | Fix |
|---|---|---|
| Init:0/1 forever | wait-for loop, dependency never ready | Fix upstream Service/endpoints, add timeout |
| Init:CrashLoopBackOff | init script exits non-zero | logs -c <init> --previous, fix command |
| Init:ImagePullBackOff | init image tag/creds wrong | Fix image ref / imagePullSecrets |
| "configmap not found" | missing/wrong-namespace ref | Create it in the pod's namespace |
| App can't read shared volume | UID mismatch | Set securityContext.fsGroup |
Explore More in This Category
Explore more in this category: Kubernetes guides. Browse all DevOps Compass articles or jump to: Kubernetes, AWS, CI/CD, Containers, Monitoring, Networking.