Back to Blog
Troubleshooting

Debugging CrashLoopBackOff in Kubernetes

Step-by-step guide to diagnose and fix CrashLoopBackOff errors. Covers log analysis, common causes, and practical solutions.

Paul BrissaudPaul Brissaud
•
January 28, 2026
•
2 min read
#troubleshooting#pods

Your pod is stuck in a restart loop. Every few seconds, Kubernetes tries to start it, it fails, and the cycle repeats. The status says CrashLoopBackOff, and you're not sure where to start. This is one of the most common—and frustrating—Kubernetes errors.

Quick Answer

CrashLoopBackOff means your container keeps crashing, and Kubernetes is backing off before retrying. To diagnose:

bash
kubectl logs <pod-name> --previous

This shows logs from the last crashed container. The error message there usually points to the root cause.

What Does CrashLoopBackOff Mean?

CrashLoopBackOff is not an error itself—it's a state. It means:

  1. Your container started
  2. It crashed (exited with non-zero code)
  3. Kubernetes restarted it
  4. It crashed again
  5. Kubernetes is now waiting longer between restarts (the "backoff")

The backoff delay increases exponentially: 10s, 20s, 40s... up to 5 minutes. This prevents a broken container from consuming all cluster resources.

Common Causes

CauseHow to Identify
Application errorCheck logs for stack traces or error messages
Missing configurationLogs show "config not found" or "env var not set"
Failed liveness probekubectl describe pod shows liveness probe failures
OOMKilledLast state shows Reason: OOMKilled
Missing dependenciesLogs show connection refused to database/service
Wrong command/entrypointContainer exits immediately with code 1 or 127
Permission issuesLogs show "permission denied" or RBAC errors

Step-by-Step Troubleshooting

Step 1: Get the Pod Status

bash
kubectl get pods

Look for the RESTARTS column. A high number confirms the crash loop.

javascript
NAME                     READY   STATUS             RESTARTS   AGE
my-app-7d4b8c6f9-x2k4j   0/1     CrashLoopBackOff   5          3m

Step 2: Check the Logs

This is usually where you find the answer:

bash
# Current container logs (if it's running)
kubectl logs <pod-name>

# Previous container logs (after crash)
kubectl logs <pod-name> --previous

# Logs from a specific time range
kubectl logs <pod-name> --since=1h

# All containers in a multi-container pod
kubectl logs <pod-name> --all-containers

Look for:

  • Stack traces
  • "Error:", "Fatal:", "Exception" messages
  • Connection failures
  • Missing file/config errors

Step 3: Describe the Pod

Get detailed information about the pod's state:

bash
kubectl describe pod <pod-name>

Key sections to examine:

Last State - Shows why the container exited:

javascript
Last State:     Terminated
  Reason:       Error
  Exit Code:    1
  Started:      Mon, 27 Jan 2026 10:00:00 +0000
  Finished:     Mon, 27 Jan 2026 10:00:05 +0000

Events - Shows recent activity:

javascript
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Warning  BackOff    1m (x5 over 3m)    kubelet            Back-off restarting failed container

Step 4: Check Exit Codes

Common exit codes and their meanings:

Exit CodeMeaning
0Success (can still cause CrashLoop if restartPolicy: Always and container exits normally)
1General application error
126Command invoked cannot execute (permission issue)
127Command not found
137SIGKILL (OOMKilled or manual kill)
139SIGSEGV (Segmentation fault)
143SIGTERM (Graceful termination)

Solutions by Cause

Cause A: Application Error

Symptoms: Logs show stack traces, unhandled exceptions, or application-specific errors.

Fix: This is a code issue. Debug locally, fix the bug, rebuild and redeploy.

bash
# Test locally first
docker run -it <your-image> sh

Cause B: Missing Configuration

Symptoms: Logs show "environment variable not set" or "config file not found".

Fix: Ensure ConfigMaps and Secrets are properly mounted:

yaml
env:
- name: DATABASE_URL
  valueFrom:
    secretKeyRef:
      name: db-credentials
      key: url

Verify the Secret exists:

bash
kubectl get secret db-credentials
kubectl get secret db-credentials -o json | jq '.data | map_values(@base64d)'

Cause C: Liveness Probe Failing

Symptoms: kubectl describe pod shows repeated liveness probe failures before the crash.

javascript
Warning  Unhealthy  10s (x3 over 30s)  kubelet  Liveness probe failed: connection refused

Fix: The probe might be checking too early or too aggressively. Adjust the configuration:

yaml
livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 30  # Give app time to start
  periodSeconds: 10
  failureThreshold: 3      # Allow some failures

Important: If your app takes time to initialize, consider using a startupProbe instead of increasing initialDelaySeconds:

yaml
startupProbe:
  httpGet:
    path: /health
    port: 8080
  failureThreshold: 30
  periodSeconds: 10
# This gives up to 5 minutes (30 x 10s) for startup

Cause D: OOMKilled

Symptoms: Last state shows Reason: OOMKilled, exit code 137.

Fix: Increase memory limits:

yaml
resources:
  limits:
    memory: "512Mi"  # Increase this
  requests:
    memory: "256Mi"

See our detailed guide: How to Fix Kubernetes OOMKilled Pods

Cause E: Wrong Command or Entrypoint

Symptoms: Container exits immediately with code 1 or 127. Logs are empty or show "command not found".

Fix: Verify the command in your deployment matches what the image expects:

yaml
containers:
- name: my-app
  image: my-app:v1
  command: ["/app/start.sh"]  # Make sure this exists in the image
  args: ["--config", "/etc/config/app.yaml"]

Test interactively:

bash
kubectl run debug --rm -it --image=<your-image> -- sh
# Then manually run your command

Cause F: Missing Dependencies

Symptoms: Logs show connection errors to databases, APIs, or other services.

Fix:

  1. Verify the dependency is running: kubectl get pods -A | grep <service>
  2. Check network policies aren't blocking traffic
  3. Verify service DNS resolution: kubectl run debug --rm -it --image=busybox -- nslookup <service-name>
  4. Use init containers to wait for dependencies:
yaml
initContainers:
- name: wait-for-db
  image: busybox
  command: ['sh', '-c', 'until nc -z postgres-svc 5432; do sleep 2; done']

Debugging Tips

Get Termination Details Directly

Quickly check why the last container terminated:

bash
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].lastState.terminated}' | jq

Run a Debug Container

If the container crashes too fast to debug:

bash
# Override the command to keep it running
kubectl run debug --rm -it --image=<your-image> --command -- sleep infinity

# Then exec into it
kubectl exec -it debug -- sh

Use Ephemeral Debug Containers (K8s 1.25+)

Attach a debug container to a running or crashed pod without modifying it:

bash
kubectl debug <pod-name> -it --image=busybox --target=<container-name>

This is useful when the original image doesn't have debugging tools.

Check Events Cluster-Wide

bash
kubectl get events --sort-by='.lastTimestamp' | grep <pod-name>

Watch the Restart Cycle

bash
kubectl get pods -w

Practice This Scenario

Practice This Scenario
mediumMonitoring & Debugging
Probes Drift
The app works perfectly in local tests. In Kubernetes? It never stays up long enough to find out.
15 min
Start Challenge

In this hands-on challenge, you'll:

  • Investigate why a pod keeps getting killed during startup
  • Understand the relationship between probes and container lifecycle
  • Fix the configuration to achieve stable operation

Prevention Tips

  1. Always check logs locally first - Run docker run before deploying to Kubernetes
  2. Use startup probes for slow-starting apps - Don't abuse initialDelaySeconds
  3. Set appropriate resource limits - Monitor actual usage with kubectl top pods
  4. Handle signals gracefully - Implement proper SIGTERM handling
  5. Add health endpoints - Make debugging easier with /health and /ready endpoints

Written by

Paul Brissaud

Paul Brissaud

Paul Brissaud is a DevOps / Platform Engineer and the creator of Kubeasy. He believes Kubernetes education is often too theoretical and that real understanding comes from hands-on, failure-driven learning.

TwitterGitHub

On this page

  • Quick Answer
  • What Does CrashLoopBackOff Mean?
  • Common Causes
  • Step-by-Step Troubleshooting
  • Step 1: Get the Pod Status
  • Step 2: Check the Logs
  • Step 3: Describe the Pod
  • Step 4: Check Exit Codes
  • Solutions by Cause
  • Cause A: Application Error
  • Cause B: Missing Configuration
  • Cause C: Liveness Probe Failing
  • Cause D: OOMKilled
  • Cause E: Wrong Command or Entrypoint
  • Cause F: Missing Dependencies
  • Debugging Tips
  • Get Termination Details Directly
  • Run a Debug Container
  • Use Ephemeral Debug Containers (K8s 1.25+)
  • Check Events Cluster-Wide
  • Watch the Restart Cycle
  • Practice This Scenario
  • Prevention Tips
KubeasyKubeasy

Master Kubernetes through hands-on challenges and real-world scenarios. Free, open-source learning platform for developers.

Product

  • Challenges
  • Documentation
  • CLI Tool

Community

  • GitHub
  • Discord
  • Contribute

Legal

  • Privacy
  • Terms
  • License

© 2025 Kubeasy. Open source under Apache License 2.0.

Related Articles

How to Fix Kubernetes OOMKilled Pods
Troubleshooting

How to Fix Kubernetes OOMKilled Pods

Read more
KubeasyKubeasyKubeasy
  • Challenges
  • Blog
  • Documentation
Sign InTry Demo