How to fix CrashLoopBackOff in Kubernetes

By Hackademy. Updated . Output from a real Kubernetes v1.35 cluster.

The short answer

CrashLoopBackOff is not an error in itself. It means a container in the pod started, exited, was restarted, and exited again, so the kubelet is now waiting before the next restart, with a delay that doubles each time up to five minutes. The usual causes are an application that exits at startup (a missing environment variable, Secret or config file, or a bad command), a liveness probe that fails and gets the container killed, and a process that is killed for using more memory than its limit. To diagnose it, run kubectl get pods to see STATUS and RESTARTS, kubectl logs POD --previous to read what the crashed run printed, and kubectl describe pod POD to see the Last State, its reason and exit code, and the pod's events. Fix the cause in the Deployment, for example by adding the missing variable or correcting the probe, and let the rollout replace the pods.

Confirm the pod is crash looping

kubectl get pods shows the symptom. READY is 0/1, RESTARTS keeps climbing, and STATUS flips between Error (the container has just exited) and CrashLoopBackOff (the kubelet is waiting before it tries again). Both are the same problem caught at different moments.

$ kubectl get pods -l app=crasher
NAME                       READY   STATUS   RESTARTS      AGE
crasher-74dd586564-pf9nn   0/1     Error    3 (35s ago)   50s
$ kubectl get pods broken crash
NAME     READY   STATUS             RESTARTS     AGE
broken   0/1     ErrImagePull       0            15s
crash    0/1     CrashLoopBackOff   1 (8s ago)   15s

Compare the two pods above. broken never started because its image could not be pulled, so it has no restarts and no logs. crash did start, ran, and exited. A crash loop always means the container got as far as running, so the answer is usually in what it printed.

Read the logs of the crashed run

kubectl logs prints the output of the current container instance. Between restarts that is often the run that has just failed, but if a new run has already started it can be empty or misleading. Add --previous (or -p) to read the instance before the current one, which is the run that crashed. With more than one container in the pod, name it with -c.

$ kubectl logs crash
fatal: DB_PASSWORD is not set
booting orders-api

Here the application says exactly what is wrong: it refuses to start without a database password. That is the most common crash loop of all, a variable, Secret or ConfigMap key the Deployment never passes to the container. The fix is in the pod template, for example kubectl set env deployment/orders --from=secret/orders-db --prefix=DB_, which starts a rollout with the new environment.

Logs are kept on the node only for recent instances. If the pod has restarted many times and --previous cannot retrieve anything, read the Last State in kubectl describe instead, or catch the next run with kubectl logs -f as it starts.

Check the exit code and the events

kubectl describe pod shows the container's current State and its Last State, with a reason and an exit code. The exit code narrows the cause quickly:

  • Exit code 1 (or another small number): the application chose to exit, usually after printing an error. Read the logs.
  • Exit code 137 with reason OOMKilled: the container used more memory than its limit and the kernel killed it. Raise the limit or reduce usage.
  • Exit code 0 with reason Completed: the process finished, or was stopped cleanly. A Deployment's pods restart even after a clean exit, so a command that runs once and ends will loop. A failing liveness probe can also produce this.
  • Exit code 127 or 126: the command in the image could not be found or run. Check command and args in the pod spec.
$ kubectl describe pod/crasher-74dd586564-pf9nn
    State:          Terminated
      Reason:       Error
      Exit Code:    1
      Started:      Sun, 27 Sep 2026 20:14:26 +0100
      Finished:     Sun, 27 Sep 2026 20:14:26 +0100
    Last State:     Terminated
      Reason:       Error
      Exit Code:    1
      Started:      Sun, 27 Sep 2026 20:14:04 +0100
      Finished:     Sun, 27 Sep 2026 20:14:04 +0100
    Ready:          False
    Restart Count:  3

The events at the end of the same output finish the story. A BackOff warning reading Back-off restarting failed container is the kubelet applying the delay. Its message is the same whatever the cause, so treat it as confirmation, not a diagnosis.

Rule out a failing liveness probe

Sometimes the application is fine and Kubernetes is the one restarting it. A liveness probe that checks the wrong path or port, or that gives a slow starter too little time, fails and the kubelet kills the container. The logs look healthy, and the Last State can even say Completed, because the process shut down cleanly when asked.

$ kubectl describe pod lively
    State:          Waiting
      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Sun, 27 Sep 2026 20:15:28 +0100
      Finished:     Sun, 27 Sep 2026 20:15:33 +0100
    Ready:          False
    Restart Count:  3
    Liveness:       http-get http://:80/alive delay=2s timeout=1s period=2s #success=1 #failure=2

The events for this pod say Liveness probe failed: HTTP probe failed with statuscode: 404 and Container web failed liveness probe, will be restarted. The probe asks for /alive, which nginx does not serve. Point the probe at a path the application really answers, give slow starters a startupProbe or a longer initialDelaySeconds, and keep liveness checks off external dependencies such as the database, which belong in a readiness probe.

Practise it on a simulated cluster

These missions in the Kubernetes Simulator break a cluster in this way and leave you to fix it. Free in your browser, nothing to install.

Start CrashLoopBackOff

Questions

How long does Kubernetes wait between restarts in CrashLoopBackOff?

The kubelet uses an exponential back-off: roughly 10 seconds, then 20, then 40, doubling up to a cap of five minutes. If a container then runs for ten minutes without trouble, the timer resets. That is why a crash loop can look idle for minutes at a time.

Does deleting the pod fix CrashLoopBackOff?

Only if the cause was temporary. The Deployment replaces the pod with an identical one, which will crash the same way if the spec or its configuration is wrong. Fix the cause in the Deployment instead and let the rollout replace the pods.

Why does kubectl logs show nothing for a crashing pod?

You may be reading a new run that has not printed anything yet. Use kubectl logs POD --previous for the run that crashed. If the container fails before the process starts, for example because the command does not exist, there are no logs, and kubectl describe pod shows the reason in Last State and the events.

AboutGuidesCompare

PrivacyCookiesTerms

Hackademy is a trading name of Mather Software Ltd, registered in England and Wales, company number 17443861. ICO registration ZC256628.

Contact: support@mathersoftware.com© 2026 Mather Software Ltd