CrashLoopBackOff

KUBERNETES RUNBOOK

CrashLoopBackOff

Understand why a container keeps restarting, collect the right evidence, follow the matching branch, fix the cause and verify recovery.

What you are trying to discover: why the process inside the container terminated. CrashLoopBackOff is the restart/backoff symptom, not the root cause.

What does CrashLoopBackOff mean?

Your container started, stopped, and Kubernetes is trying to restart it. Because it keeps failing, Kubernetes waits progressively longer between attempts. Common causes include application errors, memory limits, bad configuration, failing liveness probes, incorrect commands and unavailable dependencies.

60-second diagnosis

kubectl get pods -n <namespace>
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace> --previous

What each command does: get pods confirms status and restart count. describe pod shows current/previous container state and events. logs --previous retrieves logs from the container instance that just terminated.

Troubleshooting flow

Pod is restarting↓1. Describe the pod↓2. Find Last State → Terminated↓
OOMKilled → check memory limit and usage → OOMKilled troubleshooting
Error / non-zero exit → previous logs
Completed / exit 0 → command or workload design
Probe failures in Events → inspect liveness/startup probe configuration

Step 1 — Confirm the pod and restart count

kubectl get pods -n <namespace>
NAME                      READY   STATUS             RESTARTS      AGE
payments-7f6b8c9d-x2k9p   0/1     CrashLoopBackOff   7 (34s ago)   8m

What to check: READY 0/1 means the container is not ready, CrashLoopBackOff means repeated failure with restart backoff, and an increasing RESTARTS confirms recurrence. Look for CrashLoopBackOff and a restart count that keeps increasing. If the pod has multiple containers, identify which container is restarting:

kubectl get pod <pod> -n <namespace> -o jsonpath="{range .status.containerStatuses[*]}{.name}{"  restarts="}{.restartCount}{"\n"}{end}"

Step 2 — Check Last State

kubectl describe pod <pod> -n <namespace>

Under the affected container, look for output similar to:

State:
  Waiting:
    Reason: CrashLoopBackOff
Last State:
  Terminated:
    Reason: OOMKilled
    Exit Code: 137
Restart Count: 6
How to read this:
State = what the container is doing now.
Last State = what happened to the previous instance.
Reason = Kubernetes/runtime explanation for termination.
Exit Code = process termination code.
Restart Count = how often Kubernetes has restarted this container.

If Reason is OOMKilled, use the OOMKilled runbook. If Reason is Error, continue with previous logs.

Step 3 — Read the logs from the crashed container

kubectl logs <pod> -n <namespace> --previous

Why --previous matters: the current container may have only just restarted. The useful exception often belongs to the previous terminated instance.

For a multi-container pod:

kubectl logs <pod> -n <namespace> -c <container> --previous

If logs show a configuration error

Examples include missing environment variables, invalid configuration files or missing Secret/ConfigMap keys.

kubectl get pod <pod> -n <namespace> -o yaml
kubectl get configmap -n <namespace>
kubectl get secret -n <namespace>

Verify names, namespaces, referenced keys and mount paths. Avoid printing decoded secret values into shared logs.

If logs show connection errors

Look for DNS failures, timeouts, authentication errors or connection refused. Confirm the required database, queue, API or other dependency exists and is reachable. An application that exits immediately whenever a dependency is briefly unavailable may also need more resilient startup behavior.

Step 4 — Check Events for probe failures

kubectl describe pod <pod> -n <namespace>

At the bottom, inspect Events. A liveness problem might look like:

Warning  Unhealthy  Liveness probe failed:
HTTP probe failed with statuscode: 500

Now inspect the workload probe configuration:

kubectl get pod <pod> -n <namespace> -o yaml

Check the probe type, path, port, initial delay, timeout, period and failure threshold. Also determine whether the application is genuinely unhealthy or merely slow to start. For slow startup, a startupProbe can protect the application from liveness checks until startup succeeds.

Correct probe settings in the workload manifest/source of truth and deploy through your normal delivery process. Do not simply disable liveness checks to make the symptom disappear.

Step 5 — Check command and entrypoint

If the process exits immediately, inspect image behavior plus Kubernetes command and args.

kubectl get pod <pod> -n <namespace> -o yaml

Look for wrong binary paths, invalid flags, missing executable permissions, shell-script errors, or a command that successfully finishes even though the workload is expected to stay running.

Common mistakes

  • Deleting/restarting the pod before collecting previous logs and events.
  • Treating CrashLoopBackOff itself as the root cause.
  • Increasing memory without confirming OOMKilled and usage behavior.
  • Disabling probes instead of correcting the probe or application health.
  • Editing a generated pod directly instead of fixing the owning Deployment/StatefulSet and source of truth.

Verify the fix

kubectl get pods -n <namespace> -w
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace>

Confirm the pod becomes Ready, restart count stops increasing, application logs are healthy, and relevant service metrics remain stable for longer than the previous failure interval.

Quick command reference

# Status and restarts
kubectl get pods -n <namespace>

# State, last state and events
kubectl describe pod <pod> -n <namespace>

# Logs from the crashed instance
kubectl logs <pod> -n <namespace> --previous

# Full pod specification
kubectl get pod <pod> -n <namespace> -o yaml

# Recent namespace events
kubectl get events -n <namespace> --sort-by=.lastTimestamp