Kubernetes Pod CrashLoopBackOff: Quick Fix and Why
Pod keeps crashing? Check logs with kubectl logs, then fix the config or resource limit. Here's the real fix and why it works.
Yeah, CrashLoopBackOff is annoying. Your pod starts, crashes, Kubernetes tries again, and it just keeps looping. The good news: the fix is usually simple once you know where to look.
First, the fix
- Run
kubectl logs <pod-name> -n <namespace>. This is the single most useful command. It shows the last container output before it died. If the pod has multiple containers, add-c <container-name>. - If logs are empty (pod never started), run
kubectl describe pod <pod-name> -n <namespace>. Look at theStateandLast Statefields. The reason tells you exactly what failed —OOMKilled,Error,CrashLoopBackOff. - Common causes:
- OOMKilled: the container ran out of memory. Fix: increaseresources.limits.memoryin your deployment YAML. Or reduce memory usage in the app.
- Exit code 1 or 127: your app crashed or command not found. Fix: check the Docker image works locally first. Common mistake: wrong entrypoint path.
- Liveness probe failing: the health check endpoint returns non-200. Fix: check the probe path and port. Or increaseinitialDelaySecondsif the app starts slow. - After fixing, delete the pod:
kubectl delete pod <pod-name> -n <namespace>. Kubernetes recreates it with the new Deployment spec. Or update the Deployment and it rolls out automatically.
Why this works
CrashLoopBackOff is Kubernetes' way of saying "I tried, but the container keeps failing." The loop is intentional — it backs off exponentially (10s, 20s, 40s...) to avoid wasting resources. The actual problem is almost never Kubernetes itself. It's either your app code, configuration, or resource limits.
The reason step 1 is so effective: logs show the last thing the app printed before crashing. If it's a syntax error in Python, you see the traceback. If it's a Java OOM, you see the stack trace. No guessing.
For OOMKilled: when the container hits the memory limit, the kernel kills it (OOM killer). Kubernetes sees exit code 137 (SIGKILL). Setting limits.memory higher gives the app breathing room. But don't set it too high — nodes have finite memory. Check kubectl top nodes.
For liveness probes: if the probe fails, Kubernetes restarts the pod thinking the app is dead. But if the app takes 30 seconds to start and the probe fires after 10, it'll kill the pod before it's ready. That's what initialDelaySeconds fixes.
Less common variations
Container keeps restarting but logs show nothing
This often means the container exits before writing logs. Typical scenario: a binary that runs a one-off task and finishes (exit 0). But Kubernetes expects a long-running process. Fix: make the app run in a loop, or use a command like tail -f /dev/null if it's a placeholder. But really, don't use long-running pods for batch jobs — use Jobs instead.
Init container crash
If an init container fails, the whole pod never starts. Check kubectl logs <pod-name> -c <init-container-name>. The same fix applies — look at the exit code and logs. Common: init container tries to download a file but has no network access. Make sure it has correct permissions and DNS.
Node resource pressure
Sometimes the pod isn't crashing — the node evicts it because the node runs out of resources. Check kubectl describe pod for Evicted status. Fix: add resource requests and limits to all pods. Use node affinity to distribute load.
ConfigMap or Secret not mounted
If your app needs a config file from ConfigMap and it's missing, the app crashes at startup. Check kubectl describe pod for events like FailedMount. Fix: verify the ConfigMap exists in the same namespace. Use kubectl get configmap.
Prevention
- Always set
resources.requestsandresources.limits. Without them, pods can get evicted or OOM-killed without warning. - Set liveness and readiness probes with realistic
initialDelaySeconds. A good rule:initialDelaySeconds: 5for a fast app,30for a Java app. - Test your Docker image locally. Run
docker run --rm -it your-image:tagand check if it stays alive. If it exits after 1 second, that's your problem. - Use
kubectl logs --previousto see logs from the last crash, not the current restart. This is gold when the container restarts immediately and you miss the error. - Set a reasonable
restartPolicy. Default isAlwaysfor pods. For batch jobs, useOnFailureorNever.
That's it. Most CrashLoopBackOff issues are solved in two commands: kubectl logs and kubectl describe pod. Don't overthink it.
Was this solution helpful?