Debugging CrashLoopBackOff: Why Pods Crash and How to Fix Them
Fast recall
Quick revision
Core answer
CrashLoopBackOff means the container started, exited, and kubelet is backing off before the next restart (10s → 20s → 40s → ... up to 5 min). Root causes: (1) App crashes on startup — missing config, bad DB creds, port conflict, OOMKilled; (2) Liveness probe failing — endpoint doesn't exist or app is slow to warm up; (3) Init container failing; (4) Missing Secret/ConfigMap. Debug order: kubectl describe pod (exit code + reason) → kubectl logs --previous (logs of the crashed container) → kubectl logs -f if still running → check probes, init containers, and env/secret refs. Exit code 137 = OOMKilled; 143 = SIGTERM.Whether you know to read `--previous` logs, interpret exit codes, and distinguish app crashes from probe failures
Only reading current logs (empty because the container restarted) and missing `--previous`; or confusing probe-induced kills with app crashes
Explain exit code table (137 OOMKilled, 1 app error, 143 SIGTERM, 139 SIGSEGV), `kubectl debug` ephemeral containers, `terminationMessagePath`, backoff timing, startup probe to prevent liveness-during-warmup kills, and sidecar crashes affecting the main container
Interview-ready guide
Interview answer
CrashLoopBackOff means the container keeps exiting and kubelet is waiting before the next restart with exponential backoff from 10 seconds up to 5 minutes. The symptom is a loop; the root cause is one of a handful of things.
The diagnostic flow I use
kubectl describe podand read the Last State section — that gives the exit code and reason. 137 means OOMKilled, 1 is an app error, 143 is SIGTERM, 2 is an ENTRYPOINT issue.kubectl logs POD --previous— this is the critical step most people miss. The current container just started sokubectl logsreturns almost nothing;--previousshows the last crashed container's output which usually has the stack trace.- Check the Events section for liveness probe failures — if the probe is killing the pod during startup, the app didn't crash, it was SIGKILLed.
The big four root causes
- App crash on startup — bad DB credentials, missing config, port conflict. Fix via logs: "password authentication failed" or "Could not resolve placeholder".
- Liveness probe killing a slow-starting JVM — Spring Boot takes 30 to 60 seconds to warm up; liveness fires before then, kubelet SIGKILLs. Fix: add a startupProbe so liveness only starts after startup succeeds once.
- Init container failing — pod shows
Init:CrashLoopBackOffand main container never starts. Check init logs with-c INIT_NAME --previous. - OOMKilled (exit code 137) — cgroup memory limit hit. Raise memory limit and set
-XX:MaxRAMPercentage=75so JVM respects the container limit.
Probe configuration
- Use
/actuator/health/livenessfrom Spring Boot 2.3+, not aggregate/actuator/health— the liveness endpoint returns UP even if DB is temporarily down, so transient DB issues don't cause pointless restarts. - startupProbe plus livenessProbe plus readinessProbe is the production pattern — startup covers warm-up, liveness restarts on true hangs, readiness takes the pod out of Service rotation during transient issues.
Tools that help when logs aren't enough
kubectl debug --image=busybox --target=CONTAINERattaches an ephemeral container sharing process and filesystem namespace — you can inspect /proc, environment, mounted configs without rebuilding the image.terminationMessagePathlets the container write its cause-of-death; kubelet surfaces it indescribe pod, so root cause is visible even if logs were lost.
Escalation pattern
- One pod — app bug, config typo, probe misconfig.
- All pods of one Deployment — bad image, wrong Secret, env misconfig.
- Many Deployments — node issue, DNS failure cluster-wide, or platform-level problem.
Production hardening I apply
- Startup probe on every JVM service.
-XX:+HeapDumpOnOutOfMemoryErrorwriting to an emptyDir at /dumps so I can copy the dump out before the pod is replaced.- Prometheus alert on restart rate per 10 minutes — catches CrashLoop before users notice.
Debugging `CrashLoopBackOff`: Why Pods Crash and How to Fix Them
Direct Answer
CrashLoopBackOff means the container started, exited, and kubelet is backing off before the next restart (10s → 20s → 40s → ... up to 5 min). Root causes: (1) App crashes on startup — missing config, bad DB creds, port conflict, OOMKilled; (2) Liveness probe failing — endpoint doesn't exist or app is slow to warm up; (3) Init container failing; (4) Missing Secret/ConfigMap. Debug order: kubectl describe pod (exit code + reason) → kubectl logs --previous (logs of the crashed container) → kubectl logs -f if still running → check probes, init containers, and env/secret refs. Exit code 137 = OOMKilled; 143 = SIGTERM.
Common Mistakes & Pitfalls
Only reading current logs (empty because the container restarted) and missing --previous; or confusing probe-induced kills with app crashes
Check your understanding
Answer these without looking back at the article.
- What is the difference between a startupProbe and a livenessProbe with `initialDelaySeconds`?
- How do you capture a heap dump when a pod is being OOMKilled?
- How does `kubectl debug` ephemeral containers differ from `kubectl exec`?
- Why should you use `/actuator/health/liveness` instead of `/actuator/health` for liveness?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.