CrashLoopBackOff is one of the most common Kubernetes errors, and one of the most poorly explained by kubectl get pods alone. Here's how to actually diagnose it.
Step 1: Confirm what's happening
kubectl get podsNAME READY STATUS RESTARTS AGE
api-7d9f8c9d-x2n4q 0/1 CrashLoopBackOff 6 4m
The status means: the container starts, exits (crashes or completes), and Kubernetes keeps restarting it with an increasing backoff delay.
Step 2: Read the logs from the crashed container
kubectl logs api-7d9f8c9d-x2n4q --previousThe --previous flag is essential — it shows logs from the last terminated container, not the current (likely empty) restart attempt.
Step 3: Check the exit code and reason
kubectl describe pod api-7d9f8c9d-x2n4qLook at the Last State section:
Last State: Terminated
Reason: Error
Exit Code: 1
Common exit codes:
| Exit Code | Meaning |
|---|---|
| 0 | Container exited cleanly (often a misconfigured entrypoint for a long-running service) |
| 1 | Application error — check logs |
| 137 | OOMKilled — the container exceeded its memory limit |
| 143 | SIGTERM — often a graceful shutdown that took too long |
Step 4: Match the exit code to a fix
OOMKilled (137): Raise the memory limit or fix a memory leak.
resources:
limits:
memory: "512Mi"
requests:
memory: "256Mi"Application error (1): Usually a missing environment variable, bad config, or failed dependency connection — the logs from Step 2 will show the stack trace.
Readiness/liveness probe failing: If the app takes longer to boot than the probe allows, increase initialDelaySeconds.
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10Step 5: Verify the fix
kubectl rollout restart deployment api
kubectl get pods -wWatch for RESTARTS to stop increasing and STATUS to settle on Running.
Quick reference checklist
kubectl logs <pod> --previouskubectl describe pod <pod>and check the exit code- Match exit code to cause (OOM, app error, probe timeout)
- Apply the fix and roll out again
A crash caused by a genuinely missing environment variable often traces back to how ConfigMaps and Secrets are wired into the pod spec, and if the crash is really about a node running out of schedulable capacity rather than the application itself, Karpenter is the piece worth checking next.
Other exit codes and what they mean
The table above covers the most common cases, but a few more show up often enough to be worth recognizing on sight:
| Exit Code | Meaning |
|---|---|
| 126 | Command found but not executable — often a missing chmod +x on an entrypoint script baked into the image |
| 127 | Command not found — the entrypoint or CMD references a binary that doesn't exist in the final image (common after a multi-stage build accidentally leaves a binary out of the runtime stage) |
| 139 | Segmentation fault (SIGSEGV) — usually a genuine bug in a compiled binary or native dependency, not application-level config |
Exit codes 126 and 127 in particular are worth checking first when a pod crashes immediately on every single attempt with no partial startup logs at all — that pattern points at the container never actually starting the intended process, not at the application failing after starting.
When the pod isn't even reaching CrashLoopBackOff
A related but distinct failure worth distinguishing: ImagePullBackOff looks similar in kubectl get pods output but has a completely different cause — Kubernetes can't pull the image at all (wrong tag, private registry auth missing, typo in the image name), and the container never starts even once. kubectl describe pod distinguishes these clearly in the Events section:
Failed to pull image "myapp:v2": rpc error: code = NotFound
vs. a genuine crash loop, where the image pulls fine and the container actually starts and exits repeatedly. Treating an ImagePullBackOff as a CrashLoopBackOff (and looking for application bugs) wastes time on a problem that's actually about registry access or a bad tag, not application code.
Checking events across the whole namespace
For a crash happening intermittently, checking events at the namespace level (not just one pod) can catch a pattern a single describe pod misses — a node under memory pressure evicting several pods at once, for instance, looks very different from an isolated application bug:
kubectl get events -n my-namespace --sort-by=.lastTimestampSorted by time, this surfaces the full sequence of what actually happened across the namespace leading up to the crash, which is often the fastest way to distinguish "this one pod has a bug" from "something at the node or cluster level is causing multiple pods to fail together."
Common mistakes
- Jumping straight to raising memory/CPU limits without confirming exit code 137 (OOMKilled) is actually what happened. A different exit code needs a different fix — bumping resources won't help an application-error crash and just delays hitting the same problem again with a bigger container.
- Checking
kubectl logswithout--previouson a pod that's already restarted. The default (non---previous) logs show the current attempt, which for a freshly-restarted crashing pod is often empty or has almost nothing useful yet. - Setting
initialDelaySecondsfar higher than needed "just to be safe" after a probe-timing issue. An overly generous delay means Kubernetes takes that much longer to detect a genuinely hung container — tune it to your app's real startup time, not an arbitrary large number. - Assuming a single
describe podtells the whole story on a pod that's crashed many times. Old events age out of the Events section — for a pod that's been crash-looping for a while, the most useful current logs may already be gone, and the fix is to check soon after the behavior starts, not after it's been looping for hours.
Related reading
- Kubernetes ConfigMaps and Secrets: A Practical Guide — shares tags: kubernetes, devops, cloud (same category).
- CI/CD Pipelines Explained: From Commit to Production — shares tags: devops, cloud.
- Understanding Cloud Cost Optimization Basics — shares tags: cloud, devops.
- Infrastructure as Code: Why Terraform Won — shares tags: devops, cloud.
- Karpenter: Faster, Simpler Kubernetes Autoscaling on AWS — shares tags: kubernetes, cloud.
- Argo CD and GitOps: Continuous Delivery for Kubernetes — shares tags: kubernetes, devops.