🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

Kubernetes Init Container Failing — How to Debug and Fix It

Init container errors block your main containers from starting. Here's how to find the root cause fast — OOMKilled, permission errors, missing secrets, and more.

DevOpsBoysMay 13, 20264 min read
Share:Tweet

Your pod is stuck in Init:0/1 or Init:CrashLoopBackOff. The main container hasn't started yet. Here's how to debug init container failures fast.


Understand the Lifecycle

Init containers run before your main container starts. All init containers must complete successfully (exit 0) before the main container is created.

Pod starts →
  init-container-1 runs →
  init-container-2 runs →
  main container starts

If any init container fails, the pod stays in Init:x/y and Kubernetes retries with backoff (CrashLoopBackOff pattern).


Step 1 — Identify the Failing Init Container

bash
# See pod status
kubectl get pod <pod-name> -n <namespace>
# STATUS will show: Init:0/1, Init:CrashLoopBackOff, etc.
 
# Full details
kubectl describe pod <pod-name> -n <namespace>
# Look for: Init Containers section → State, Exit Code, Last State

The describe output will show which init container failed and its exit code.


Step 2 — Read the Init Container Logs

bash
# Logs from specific init container
kubectl logs <pod-name> -n <namespace> -c <init-container-name>
 
# Previous run logs (after restart)
kubectl logs <pod-name> -n <namespace> -c <init-container-name> --previous

Common exit codes:

  • Exit Code 1 — Script error or command not found
  • Exit Code 137 — OOMKilled (container ran out of memory)
  • Exit Code 126 — Permission denied (can't execute file)
  • Exit Code 1 with "No such file" — Missing dependency or volume

Fix 1 — Init Container OOMKilled

If kubectl describe shows OOMKilled or exit code 137:

yaml
initContainers:
  - name: db-migrate
    image: myapp:latest
    command: ["python", "manage.py", "migrate"]
    resources:
      requests:
        memory: "128Mi"
      limits:
        memory: "512Mi"   # Increase this

Database migrations and data processing init containers often need more memory than defaults.


Fix 2 — Init Container Can't Reach a Service

A common pattern: init container waits for a database or service to be ready before main app starts.

bash
# Init container logs might show:
# "Connection refused: postgres:5432"
# "dial tcp: lookup redis: no such host"

Fix — use proper wait-for script:

yaml
initContainers:
  - name: wait-for-postgres
    image: busybox:1.36
    command:
      - sh
      - -c
      - |
        until nc -z postgres-service 5432; do
          echo "Waiting for postgres..."
          sleep 2
        done
        echo "Postgres is ready"

Or check if the target service actually exists:

bash
kubectl get svc postgres-service -n <namespace>
# If not found → service name is wrong in init container config

Fix 3 — Missing Secret or ConfigMap

bash
# Init container logs:
# "Error: secret "db-credentials" not found"
# or pod never starts with: "CreateContainerConfigError"
bash
# Check if secret exists
kubectl get secret db-credentials -n <namespace>
 
# Check if it's in the right namespace
kubectl get secrets -n <namespace>
 
# Verify secret key names match what init container expects
kubectl describe secret db-credentials -n <namespace>

Fix the reference in your pod spec:

yaml
initContainers:
  - name: init-config
    image: busybox
    envFrom:
      - secretRef:
          name: db-credentials   # Must exist in same namespace

Fix 4 — Permission Denied in Init Container

If init container runs a script but gets Permission denied:

yaml
initContainers:
  - name: init-scripts
    image: myapp:latest
    command: ["/bin/sh", "/scripts/init.sh"]
    securityContext:
      runAsUser: 0    # Run as root for init operations

Or fix the Dockerfile to make the script executable:

dockerfile
COPY scripts/init.sh /scripts/init.sh
RUN chmod +x /scripts/init.sh

Fix 5 — Init Container Image Pull Failing

bash
kubectl describe pod <pod-name> | grep -A5 "Init Containers" | grep -E "Image|State"
# Shows: "ImagePullBackOff" or "ErrImagePull"
bash
# Check image name spelling
# Check if imagePullSecrets are configured for private registry
 
kubectl get pod <pod-name> -o yaml | grep -A5 imagePullSecrets

Fix 6 — Init Container Volume Mount Issues

bash
# Init container logs: "stat /data: no such file or directory"
# or: "permission denied: /data/config.yaml"
yaml
volumes:
  - name: shared-data
    emptyDir: {}
 
initContainers:
  - name: init-data
    image: busybox
    command: ["sh", "-c", "echo 'ready' > /data/status"]
    volumeMounts:
      - name: shared-data
        mountPath: /data
 
containers:
  - name: main-app
    image: myapp:latest
    volumeMounts:
      - name: shared-data
        mountPath: /data    # Same volume, main app can read it

Quick Debug Checklist

bash
# 1. What's the status?
kubectl get pod <pod> -n <ns>
 
# 2. Which init container failed and exit code?
kubectl describe pod <pod> -n <ns> | grep -A 20 "Init Containers:"
 
# 3. What are the logs?
kubectl logs <pod> -n <ns> -c <init-container-name> --previous
 
# 4. Are secrets/configmaps present?
kubectl get secret,configmap -n <ns>
 
# 5. Can you exec into a running version of the init image?
kubectl run debug --image=<init-container-image> --restart=Never -- sleep 3600
kubectl exec -it debug -- sh

Init container failures are always fixable once you have the logs. The --previous flag is your best friend — it shows you what the failed run actually printed.

For hands-on Kubernetes debugging labs, KodeKloud has scenario-based courses that cover init containers, sidecars, and real troubleshooting workflows.

Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments