Full lesson
Explore the full explanation, examples, and visuals at your own pace.
orders-api
That restarting isn't a bug. Kubernetes does it on purpose. Take our orders-api container. It starts, runs, then crashes with exit code 1. Kubernetes doesn't give up. It waits briefly, restarts it, and the loop begins again. Why would it keep doing that?
The symptom
Here's what you'd see. READY says zero of one, so the container isn't running. STATUS reads CrashLoopBackOff, and RESTARTS shows five in four minutes. Kubernetes isn't giving up on orders-api. It keeps trying, and that persistence is exactly what we need to understand.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
orders-api 0/1 CrashLoopBackOff 5 (40s ago) 4mDesired: 1 running container
Kubernetes never decides a crash is permanent. The kubelet just compares desired state, one running container, with actual state, which is exited. That mismatch triggers a restart to close the gap. And that's useful, because many crashes are transient, like a database that isn't ready yet.
orders-api.yaml
The field that drives this is restartPolicy. With Always, the kubelet restarts the container on any exit. OnFailure restarts only after a non-zero exit code, and Never leaves it stopped. Always is the default, and Pods managed by a Deployment must use it.
apiVersion: v1
kind: Pod
metadata:
name: orders-api
spec:
restartPolicy: Always # Always | OnFailure | Never
containers:
- name: orders-api
image: shop/orders-api:1.4Each crash doubles the wait, capped at 5 minutes
The kubelet starts at about ten seconds, then doubles: twenty, forty, eighty, a hundred sixty, and finally it caps at three hundred. That backoff stops a broken container from hammering the node or its dependencies. After roughly ten healthy minutes, the timer resets. Defaults can vary by version.
Chart values
| Restart attempt | Delay (seconds) |
|---|---|
| 1st | 10 |
| 2nd | 20 |
| 3rd | 40 |
| 4th | 80 |
| 5th | 160 |
| 6th | 300 |
| 7th | 300 |
orders-api has crashed eight times in a row without a fix. Roughly how long will the kubelet wait before the next restart?
orders-api has crashed eight times in a row without a fix. Roughly how long will the kubelet wait before the next restart?
- About five minutes, the backoff cap
- About ten seconds, like the first try
- Forever, because it gives up restarting
orders-api has crashed eight times in a row without a fix. Roughly how long will the kubelet wait before the next restart?
About five minutes, the backoff cap. The delay doubles after each crash but stops growing at the cap of about five minutes. Kubernetes never gives up while restartPolicy is Always; it just retries less often until the container stays healthy.
- About five minutes, the backoff cap
- About ten seconds, like the first try
- Forever, because it gives up restarting
CrashLoopBackOff = waiting between restarts, not the cause
CrashLoopBackOff only tells you the kubelet is waiting before the next restart. It doesn't say why the app crashed. That answer lives elsewhere.
Find the real cause
Run kubectl logs with the previous flag, and you read the crashed run's output: DATABASE_URL is not set. Describe adds exit code 1 and a BackOff event. Restarting can't fix missing config, so set the variable and redeploy.
$ kubectl logs orders-api --previous
Error: DATABASE_URL is not set
$ kubectl describe pod orders-api
Last State: Terminated
Reason: Error
Exit Code: 1
Warning BackOff Back-off restarting failed containerRestarts heal transient failures; logs reveal permanent ones
Kubernetes keeps nudging reality toward the desired state, and it waits longer between each try. That heals transient failures. But when you see CrashLoopBackOff, don't wait it out. Run kubectl logs with --previous, and read why the last run died.

