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:

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

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

7. Prevention Tips

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

SymptomCauseFix
Init:0/1 foreverwait-for loop, dependency never readyFix upstream Service/endpoints, add timeout
Init:CrashLoopBackOffinit script exits non-zerologs -c <init> --previous, fix command
Init:ImagePullBackOffinit image tag/creds wrongFix image ref / imagePullSecrets
"configmap not found"missing/wrong-namespace refCreate it in the pod's namespace
App can't read shared volumeUID mismatchSet 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.