When a pod will not run, Kubernetes tells you more than most people notice. The trouble is that the status column, the first thing you see, is a symptom label rather than a diagnosis. CrashLoopBackOff means “this container keeps dying and I am waiting longer between restarts”. It does not say why.
The fastest debugging habit is to follow the same short sequence every time instead of guessing. Describe, read events, read logs, then reason about the state.
Step One: Look at the Whole Pod
Start with kubectl get pod <name> -o wide to see the node, restart count and age. Then run kubectl describe pod <name>. Skip straight to two sections: the container’s State and Last State, and the Events at the bottom.
Last State is particularly useful for crashes. It records the reason and exit code of the previous run. An exit code related to being killed for memory points to a limit problem. A plain non-zero exit from your own program points at the application. A very quick exit points at bad configuration or a missing dependency.
Events are ordered and timestamped. Read them from the bottom up in time. They often state the answer outright, such as a failed scheduling decision or a failed image pull.
Step Two: Match the Status to the Right Investigation
The status points to a stage of the pod lifecycle, and each stage fails for different reasons.
| Status | Where it failed | First things to check |
|---|---|---|
| Pending | Scheduling, before any container starts | Events for scheduling messages; resource requests versus node capacity; node selectors, taints and tolerations; unbound volume claims |
| ImagePullBackOff / ErrImagePull | Fetching the image | Image name and tag spelling; registry credentials in the pull secret; network access from the node to the registry |
| CrashLoopBackOff | Container starts then exits repeatedly | Previous container logs; exit code; configuration and secrets; liveness probe; memory limit |
| CreateContainerConfigError | Preparing the container | Missing ConfigMap or Secret referenced by the pod; invalid key names |
| Running but not ready | Container runs, readiness fails | Readiness probe path and port; app startup time; dependency availability |
Use this as a map, not a rule. Real incidents sometimes combine two causes.
Debugging Pending Pods
A pending pod has been accepted but not placed. The scheduler’s reason appears in the Events. Common ones:
- Not enough resources. The pod’s requests exceed the free capacity on any node. Requests, not actual usage, drive scheduling, so a node can look idle and still be “full”.
- Taints with no toleration, or unmatched selectors and affinity. The pod demands a node that does not exist or is off limits.
- Unbound storage. A claim waiting on a volume that cannot be provisioned, or tied to a zone where no node is available.
If the cluster autoscales, also confirm the autoscaler can add the right kind of node. Check your cluster’s current documentation for how it reports scale-up decisions.
Debugging ImagePullBackOff
This is usually mundane. Compare the image reference character by character, including registry host, repository path and tag. Check that the tag actually exists, since a tag that was pushed to a different repository is a classic mistake. For private registries, confirm the pull secret is in the same namespace as the pod and is referenced by the pod or its service account. Then check whether the node can reach the registry at all.
Debugging CrashLoopBackOff
Here the most important command is logs from the previous instance: kubectl logs <pod> --previous. The current container may have just restarted and have nothing useful to say. If the pod has several containers, name the one you want with -c.
Common reasons, roughly in order of how often they occur in practice:
- The application fails on startup. Missing environment variable, bad config value, unreachable database. The log usually says so.
- Wrong command or entrypoint. The container’s process exits immediately because the command is wrong or has nothing to keep it running.
- Out-of-memory kills. The container exceeds its memory limit and is terminated. The last state shows the reason, and logs may show nothing at all because the process had no time to log.
- Failing liveness probe. The app is fine, but the probe checks the wrong path or fires before the app is ready, so Kubernetes keeps killing a healthy container. Startup probes exist for slow starters.
- Permissions. The process runs as a non-root user and cannot write to a path or bind to a port.
When logs are empty and the container exits too fast to inspect, temporarily override the command to something like a sleep, then exec into the container and run the real command by hand. Remove the override afterwards. Ephemeral debug containers are another option where your cluster supports them.
A Realistic Example
A team deploys a new service and finds it in CrashLoopBackOff. The restart count is climbing. describe shows the last state ended with a memory-related termination, and the logs from the previous run end abruptly in the middle of startup.
That points away from a code bug and toward a limit. The memory limit in the manifest was copied from a much smaller service. They raise it modestly, redeploy, and the pod stabilises. Afterwards they watch actual memory use for a few days and tune the request and limit to match, rather than leaving the first guess in place.
The fix itself was one line. The time saved came from reading Last State instead of staring at the status.
Habits That Make This Easier
- Keep logs flowing to a central place so previous instances are not lost when pods are replaced.
- Set readiness and liveness probes deliberately and test the paths they check.
- Pin image tags to specific versions so you know what is actually running.
- Make applications fail loudly with a clear message when required configuration is missing.
Frequently Asked Questions
What does the back-off in CrashLoopBackOff mean? Kubernetes restarts a failing container with increasing delays between attempts, up to a cap. The delay prevents a broken container from consuming resources in a tight loop. It does not indicate the cause.
Why are my logs empty for a crashing pod? You may be reading the current container instead of the previous one. Use the previous flag. If it is still empty, the process may be dying before it writes anything, which suggests an entrypoint, permission or memory problem.
Can a failing readiness probe cause restarts? No. A failing readiness probe removes the pod from service endpoints but does not restart it. Restarts come from liveness probe failures, crashes or kills.
How do I tell an out-of-memory kill from an application crash? Check the container’s last state in the describe output. A termination reason tied to memory indicates the limit was hit, as opposed to a normal error exit from your own program.
Should I just delete the pod and let it recreate? Deleting can clear a transient fault, but it also destroys the evidence. Capture the describe output and previous logs first.
Next Step
Next time a pod fails, write down the status, the last state and the final event before touching anything. Do that a few times and you will notice the same few causes recurring, which tells you which guardrails, such as better probes or default resource settings, to add to your templates.
By SkyStackHub Editorial · Updated November 4, 2026
- CrashLoopBackOff
- kubectl debugging
- Kubernetes troubleshooting
- pod failures