Why Do Kubernetes Pods Restart? The 7 Causes and How to Diagnose Each (2026)
Kubernetes pods restarting? The 7 real causes — OOMKilled, CrashLoopBackOff, probe failures, eviction, node pressure — with the kubectl commands to diagnose each.
Short answer: A restarting pod is always explained by one of seven causes: (1) OOMKilled (container exceeded its memory limit), (2) application crash (CrashLoopBackOff — the process itself exits), (3) failing liveness probe, (4) node pressure eviction (node out of memory/disk), (5) preempted or deleted (scale-down, upgrades, spot reclaim), (6) image pull or config errors at startup, and (7) CPU starvation rarely — throttling degrades but doesn't kill. The first diagnostic is always kubectl describe pod — the Last State and Reason fields name the cause directly.
The 60-second diagnosis
# 1. Find the pod and its restart count
kubectl get pods -n <ns> --sort-by=.status.containerStatuses[0].restartCount
# 2. Read the autopsy report — this names the cause
kubectl describe pod <pod> -n <ns>
# → Containers → Last State: Terminated — Reason: OOMKilled / Error / Completed
# → Exit Code: 137 (OOM/SIGKILL), 1 (app error), 143 (SIGTERM)
# → Events: Liveness probe failed / Evicted / Back-off restarting
# 3. Read the dying words
kubectl logs <pod> -n <ns> --previous # logs from the container that just died
--previous is the flag everyone forgets: without it you're reading the new container's logs, not the dead one's.
The 7 causes, ranked by how often they page you
1. OOMKilled — exit code 137
The container crossed its memory limit and the kernel killed it. describe pod shows Reason: OOMKilled. Fix: raise the limit or fix the leak; set requests/limits deliberately. Full walkthrough in our Kubernetes OOMKilled guide.
Related guideKubernetes Monitoring: The Complete 2026 Guide→
2. CrashLoopBackOff — the app itself is dying
The process exits (code 1, or unhandled exception), Kubernetes restarts it with exponential backoff. Reason: Error, events show Back-off restarting failed container. The cause is in the application logs (kubectl logs --previous) — bad config, missing secret, failed migration. Full guide: CrashLoopBackOff fixes.
3. Liveness probe failures
The app runs but fails health checks (deadlock, slow startup, probe pointing at a heavy endpoint). Events: Liveness probe failed: .... Fix: fix the probe (initialDelay, timeouts, lightweight /healthz) or the underlying hang.
4. Node pressure eviction
The node ran out of memory or disk; the kubelet evicted pods to survive. Status: Evicted, or restarts correlating across many pods on one node. Diagnose: kubectl describe node <node> → look for MemoryPressure/DiskPressure conditions.
5. Deliberate termination — exit code 143 (SIGTERM)
Deployments rolling, nodes draining, HPA scaling down, spot instances reclaimed. Exit code 143 with clean shutdown logs is the platform working as intended — if it's surprising, check kubectl get events for scale/rollout activity and your PodDisruptionBudget.
6. Startup failures (ImagePullBackOff, CreateContainerConfigError)
The container never starts: wrong image tag, missing registry auth, missing ConfigMap/Secret. kubectl get pods shows the status directly; events name the missing object.
7. CPU throttling (the non-restart)
CPU limits don't kill pods — they throttle them into latency degradation while looking healthy. If users report slowness but restarts are zero, chart container_cpu_cfs_throttled_seconds_total. A different fire, frequently mistaken for this one.
The cause → command → fix table
| Cause | describe pod signature |
First move |
|---|---|---|
| OOMKilled | Reason: OOMKilled, exit 137 |
Compare limit vs actual usage; raise or fix leak |
| App crash | Reason: Error, exit 1 |
logs --previous for the exception |
| Probe failure | Liveness probe failed events |
Test the probe endpoint manually; tune timing |
| Eviction | Status: Evicted |
Check node conditions; add capacity |
| SIGTERM | exit 143, clean logs | Correlate with rollouts/scaling events |
| Throttling | (no restarts) | Chart throttle ratio; adjust CPU limit |
Stop re-diagnosing this at 3 a.m.: the alerts
# Restart spike per pod
increase(kube_pod_container_status_restarts_total[15m]) > 3
# OOM kills specifically
kube_pod_container_status_last_terminated_reason{reason="OOMKilled"} == 1
# CrashLoopBackOff status
kube_pod_container_status_waiting_reason{reason="CrashLoopBackOff"} == 1
Tag these alerts with namespace, pod, and owner labels so the page names the workload — the difference between a 5-minute and a 50-minute incident is whether the alert told you which of the seven it was. (Guance, Grafana, Datadog and every serious K8s integration ship equivalents of these rules; the queries above port directly.)
Related guideKubernetes Integration→
FAQ
Q: Why does my Kubernetes pod keep restarting?
Run kubectl describe pod and read Last State → Reason: OOMKilled (memory limit exceeded, exit 137), Error (application crash — read kubectl logs --previous), or events showing liveness probe failures or eviction. The restart reason field identifies the cause; the previous container's logs explain it.
Q: What does exit code 137 mean in Kubernetes?
The container received SIGKILL — almost always the kernel's OOM killer enforcing the container memory limit (check for Reason: OOMKilled in describe). Less commonly, an external kill -9. Exit 137 = 128 + 9 (SIGKILL). Treat as a memory-limit problem first.
Q: What does exit code 143 mean?
128 + 15 = SIGTERM: the pod was asked to stop — rolling update, scale-down, node drain, or spot-instance reclaim. If your app takes too long to shut down, Kubernetes escalates to SIGKILL after terminationGracePeriodSeconds (default 30s). Long-running jobs should handle SIGTERM gracefully.
Q: How do I see why a container restarted if the logs are gone?
kubectl logs <pod> --previous retrieves logs from the terminated container (as long as the pod still exists). For anything older, you need centralized log collection — node-local pod logs rotate away quickly, which is why production clusters ship logs to Loki/Elasticsearch/Guance/etc.
Q: How many restarts are "normal" for a pod?
Zero-to-few over weeks for a healthy service. Any sustained restart rate deserves investigation: use increase(kube_pod_container_status_restarts_total[15m]) > 3 as the alert shape. Remember restarts can also be benign batch-job behavior — judge by workload type, and always read the restart reason rather than the count alone.
Sources: Kubernetes documentation (pod lifecycle, probe behavior, exit codes, eviction). Verified 2026-08-07.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan