How to Fix CrashLoopBackOff in Kubernetes
Fix CrashLoopBackOff in Kubernetes with step-by-step troubleshooting. Debug OOMKilled, failed probes, missing configs, and image errors causing pod crash loops.
π‘ Quick Answer: CrashLoopBackOff means your container starts, crashes, and Kubernetes keeps restarting it with increasing backoff delays. Run
kubectl logs <pod>andkubectl describe pod <pod>to find the root cause β usually OOMKilled, missing env vars/configs, failed liveness probes, or application errors.Key insight: The backoff delay doubles each restart (10s, 20s, 40s, 80sβ¦ max 5 minutes). Your container IS running briefly each time β check logs from the previous crash with
--previous.Gotcha: Liveness probes should NEVER check external dependencies like databases. If the DB is down, restarting the app wonβt fix it β and causes a thundering herd.
The Problem
Your pod shows CrashLoopBackOff status and wonβt stay running:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-7b9f5c6d4-x2k8j 0/1 CrashLoopBackOff 5 (42s ago) 3mThe Solution
Step 1: Check the Crash Reason
# Get the last termination reason
kubectl describe pod myapp-7b9f5c6d4-x2k8j | grep -A5 "Last State"Common termination reasons:
| Reason | Meaning | Fix |
|---|---|---|
OOMKilled | Container exceeded memory limit | Increase resources.limits.memory |
Error (exit code 1) | Application error | Check logs |
Error (exit code 137) | SIGKILL β OOM or preemption | Increase memory or check node pressure |
Error (exit code 143) | SIGTERM β graceful shutdown failed | Check terminationGracePeriodSeconds |
Completed (exit code 0) | Container finished normally | Add a long-running process or use a Job |
Step 2: Check Logs
# Current crash attempt logs
kubectl logs myapp-7b9f5c6d4-x2k8j
# Previous crash logs (crucial β current attempt may have no output yet)
kubectl logs myapp-7b9f5c6d4-x2k8j --previous
# All containers including init containers
kubectl logs myapp-7b9f5c6d4-x2k8j --all-containersStep 3: Common Fixes
OOMKilled β increase memory:
resources:
requests:
memory: "256Mi"
limits:
memory: "512Mi" # Increase thisMissing ConfigMap or Secret:
# Check events for mount failures
kubectl describe pod myapp-7b9f5c6d4-x2k8j | grep -A3 "Events"
# "MountVolume.SetUp failed: configmap "myapp-config" not found"
# Create the missing ConfigMap
kubectl create configmap myapp-config --from-file=config.yamlBad liveness probe:
# BAD β checks database (causes thundering herd)
livenessProbe:
httpGet:
path: /health/full # Includes DB check
port: 8080
# GOOD β checks only the process itself
livenessProbe:
httpGet:
path: /healthz # Simple "am I alive" check
port: 8080
initialDelaySeconds: 15 # Give app time to start
periodSeconds: 10
failureThreshold: 3Application needs startup time:
# Add startupProbe for slow-starting apps
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
# App has 300s (30 Γ 10) to start before being killedgraph TD
A[Pod CrashLoopBackOff] --> B{Check describe pod}
B -->|OOMKilled| C[Increase memory limits]
B -->|Error exit 1| D[Check kubectl logs --previous]
B -->|Liveness probe failed| E[Fix probe or add startupProbe]
B -->|Missing config/secret| F[Create missing resource]
D --> G{Log shows what?}
G -->|Connection refused| H[Check dependent services]
G -->|Permission denied| I[Fix RBAC or file permissions]
G -->|Module not found| J[Fix container image]
G -->|No logs at all| K[Check image entrypoint]Step 4: Debug Interactively
If logs arenβt enough, override the command to keep the container alive:
# Override entrypoint to sleep (keeps pod running for debugging)
kubectl run debug-myapp --image=myapp:latest \
--overrides='{"spec":{"containers":[{"name":"debug","image":"myapp:latest","command":["sleep","3600"]}]}}' \
-- sleep 3600
# Exec into it
kubectl exec -it debug-myapp -- /bin/sh
# Try running the app manually
/app/start.shOr use ephemeral debug containers (Kubernetes 1.23+):
kubectl debug myapp-7b9f5c6d4-x2k8j -it --image=busybox --target=myappCommon Issues
CrashLoopBackOff with zero logs
The container crashes before producing any output. Check:
- Is the image correct? (
kubectl describe podβ Image field) - Is the entrypoint valid? (
docker inspect <image>locally) - Are required env vars set?
Restart count keeps increasing but pod eventually works
This is normal for pods that depend on other services not yet ready. Use init containers to wait for dependencies:
initContainers:
- name: wait-for-db
image: busybox
command: ['sh', '-c', 'until nc -z postgres-svc 5432; do sleep 2; done']OOMKilled but app normally uses less memory
Check for memory leaks. Also check if the JVM, Python, or Node.js runtime has its own memory limits that conflict with the container limit.
Best Practices
- Always set
resources.requestsANDresources.limitsβ prevents OOMKilled surprises - Liveness probes: check the process, not dependencies β if the DB is down, restarting the app makes it worse
- Use
startupProbefor slow-starting apps β prevents liveness probe from killing during startup - Set
initialDelaySecondson liveness probes β give the app time to initialize - Log to stdout/stderr β Kubernetes captures these; file-based logs are lost on crash
Key Takeaways
- CrashLoopBackOff is a symptom, not a diagnosis β always check
logs --previousanddescribe pod - The top causes are: OOMKilled, missing configs, bad liveness probes, and application errors
- Backoff delay maxes at 5 minutes β be patient or fix the root cause
- Never make liveness probes check external dependencies
- Use ephemeral debug containers or command overrides for interactive debugging
Frequently Asked Questions
What does CrashLoopBackOff mean in Kubernetes?
CrashLoopBackOff means a container keeps crashing and Kubernetes keeps restarting it with exponentially increasing delays (10s, 20s, 40s, up to 5 minutes). Itβs not an error itself β itβs Kubernetes telling you the container fails every time it starts.
How do I check CrashLoopBackOff logs?
Run kubectl logs <pod-name> --previous to see logs from the last crashed container. The --previous flag is critical because the current container may have already crashed and been replaced. Also check kubectl describe pod <pod-name> for events and exit codes.
What causes CrashLoopBackOff?
The most common causes are: application errors (unhandled exceptions), OOMKilled (memory limit too low), missing ConfigMaps or Secrets, failing liveness probes, wrong container command/entrypoint, missing environment variables, and image entrypoint errors.
How do I fix CrashLoopBackOff OOMKilled?
Check the exit code β 137 means OOMKilled. Increase the memory limit in resources.limits.memory. Use kubectl top pod to see actual memory usage. If the application has a memory leak, fix the application code or use VPA to auto-adjust limits.
How long does CrashLoopBackOff last?
Kubernetes retries with exponential backoff: 10s β 20s β 40s β 80s β 160s β 300s (5 min max). It will keep retrying indefinitely at the 5-minute interval until you fix the root cause or delete the pod.

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses β