| title | Kubernetes CrashLoopBackOff | |||||
|---|---|---|---|---|---|---|
| slug | kubernetes-crashloopbackoff | |||||
| technologies |
|
|||||
| severity | high | |||||
| tags |
|
|||||
| related |
|
|||||
| last_reviewed | 2026-06-27 |
NAME READY STATUS RESTARTS AGE
web-7c9f8d6b5b-x2kqz 0/1 CrashLoopBackOff 6 (2m11s ago) 9m
Warning BackOff 2m (x12 over 7m) kubelet Back-off restarting failed container web in pod web-7c9f8d6b5b-x2kqz_prod(...)
CrashLoopBackOff is a pod state, not an error in itself. The container starts,
exits, and the kubelet restarts it β repeatedly β applying an exponential
back-off (10s, 20s, 40s β¦ capped at 5 minutes) between attempts. The pod never
reaches a stable Running state. It is one of the most common reasons a workload
fails to come up in production.
- kubernetes (kubelet, container runtime)
high β the affected workload has zero healthy replicas (or runs degraded). If it is a single-replica Deployment or a critical DaemonSet, this is a partial or full outage for that service.
- The application process exits non-zero on startup (bad config, missing environment variable, a failed dependency it needs at boot).
- An over-aggressive
livenessProbekills the container before it finishes starting, so Kubernetes restarts a process that was actually healthy. - A required ConfigMap, Secret, or mounted file is missing or misnamed and the app aborts during initialization.
- The container command/entrypoint is wrong (binary not found, not executable).
- The container is
OOMKilledon each start (see related error).
Kubernetes reports the symptom (the restart loop), not the cause. The real
error is in the previous container's logs and in the pod's lastState. When
a container exits, the kubelet records the exit code and reason in
state.terminated, then schedules a restart after the back-off interval. Reading
the previous logs and the exit code tells you whether the process crashed
(application bug/config) or was killed by Kubernetes (probe or OOM).
# Events, restart count, last state and exit code for the pod
kubectl describe pod <pod> -n <namespace>
# Logs from the PREVIOUS (crashed) container β where the real error is
kubectl logs <pod> -n <namespace> --previous
# Exit code and termination reason, as JSON
kubectl get pod <pod> -n <namespace> \
-o jsonpath='{.status.containerStatuses[0].lastState.terminated}'
# Cluster events around the crash, newest last
kubectl get events -n <namespace> --sort-by=.lastTimestamp Last State: Terminated
Reason: Error
Exit Code: 1
Started: ...
Finished: ...
Restart Count: 6
Events:
Warning BackOff kubelet Back-off restarting failed container
A non-zero Exit Code with Reason: Error points to an application/config
failure. Reason: OOMKilled with exit code 137 points to a memory limit.
-
Read
kubectl logs <pod> --previousand fix the underlying startup failure (missing env var, unreachable dependency, bad config value). -
If the failure is a too-aggressive liveness probe, add an
initialDelaySeconds/failureThresholdthat matches real startup time, and prefer a separatereadinessProbefor slow starts:livenessProbe: httpGet: { path: /healthz, port: 8080 } initialDelaySeconds: 20 periodSeconds: 10 failureThreshold: 3
-
If
OOMKilled, raiseresources.limits.memoryor fix the leak. -
Reproduce locally with the exact image, args, and env to confirm the fix before redeploying.
kubectl get pod <pod> -n <namespace> -w
# Expect: STATUS Running, READY 1/1, and RESTARTS stops incrementing.- Make containers fail fast and log the reason to stdout/stderr.
- Keep
livenessProbeandreadinessProbedistinct; never let a slow start trip liveness. - Validate required ConfigMaps/Secrets exist in CI before deploying.
- Set memory requests/limits from observed usage to avoid OOM restart loops.
kubernetes Β· pod Β· crashloopbackoff Β· probes Β· production