CrashLoopBackOff systematisch fixen: 7 Ursachen, 1 Workflow
Die 7 häufigsten Ursachen für CrashLoopBackOff - mit kubectl-Befehlen, echten Outputs und einem Decision-Tree, der jede Ursache in unter 5 Minuten findet.
TL;DR - CrashLoopBackOff ist kein Bug, sondern ein Zustand: der Container ist gestartet, abgestürzt und wartet auf den nächsten Restart-Versuch. Die Ursache liegt nie in Kubernetes - immer im Container, im Manifest oder in der Umgebung. Dieser Workflow findet 90% aller Ursachen in unter 5 Minuten: Exit-Code lesen, vorherige Logs ansehen, Events prüfen, dann gezielt die häufigste der 7 Ursachen testen.
Was CrashLoopBackOff wirklich bedeutet
Der Begriff verwirrt mehr Engineers als nötig. CrashLoopBackOff heißt:
- Kubernetes hat den Container gestartet
- Der Container ist mit einem Exit-Code != 0 terminiert
- Kubelet hat versucht, ihn neu zu starten
- Wieder Crash
- Kubelet wartet jetzt mit exponentiellem Backoff bis zum nächsten Versuch (10s, 20s, 40s, 80s, … bis maximal 5 Minuten)
Der Container läuft also gar nicht. Die Logs des aktuellen Versuchs sind leer, weil noch kein Restart passiert ist. Sie brauchen die Logs des vorherigen Crashs - das ist die wichtigste Erkenntnis für alles, was folgt.
Der 3-Schritt-Workflow
Egal welche Ursache: Diese drei Befehle laufen immer zuerst.
Schritt 1: Exit-Code lesen
kubectl describe pod <name>
Scrolle zum Bereich Last State:
Last State: Terminated
Reason: Error
Exit Code: 137
Started: Mon, 04 May 2026 14:20:15 +0200
Finished: Mon, 04 May 2026 14:20:18 +0200
Der Exit-Code ist die wichtigste Information:
| Exit-Code | Bedeutung |
|---|---|
| 0 | Sauberer Exit (sollte nicht in CrashLoop landen, prüfen Sie restartPolicy) |
| 1 | Generic application error - Logs lesen |
| 2 | Misuse of shell builtins - meist Tippfehler im Command |
| 126 | Command not executable - Permission-Problem |
| 127 | Command not found - falscher Pfad oder fehlende Binary |
| 137 | SIGKILL - meist OOMKilled (siehe Reason) |
| 139 | SIGSEGV - Segmentation Fault, native Code hat gecrashed |
| 143 | SIGTERM - sauber beendet von außen, prüfen Sie Liveness-Probe |
Schritt 2: Vorherige Logs lesen
kubectl logs <pod> --previous
Der --previous Switch ist nicht optional. Ohne ihn sehen Sie die Logs des aktuellen (noch nicht gestarteten) Containers - also nichts. Mit ihm sehen Sie die Logs des letzten Crashs.
Schritt 3: System-Events prüfen
kubectl get events --sort-by=.lastTimestamp -n <namespace> | tail -20
System-Events zeigen Dinge, die der Container selbst nicht loggen kann: OOMKilled durch Memory-Limit, FailedMount bei Volumes, BackOff-Counts.
Die 7 häufigsten Ursachen
1. Application Error (Exit-Code 1)
Häufigste Ursache überhaupt. Der Code wirft eine Exception beim Start. Ursachen:
- Fehlende oder falsche Environment-Variable
- Datenbank nicht erreichbar (typisches Race-Condition-Symptom)
- Migrations-Skript schlägt fehl
- Config-Datei existiert nicht oder hat falsches Format
Fix-Workflow: kubectl logs <pod> --previous, Exception lesen, beheben. Bei DB-Race-Conditions: initContainer mit wait-for-db davor.
2. OOMKilled (Exit-Code 137, Reason: OOMKilled)
Container hat das Memory-Limit überschritten. Kernel hat ihn mit SIGKILL beendet.
kubectl describe pod <name> | grep -A 2 "Last State"
# Reason: OOMKilled
# Exit Code: 137
Fix: Memory-Limit erhöhen oder Memory-Leak im Code finden. Das Limit verdoppeln ist Symptom-Kosmetik - bei echten Leaks crasht der Pod nur später wieder. kubectl top pod zeigt den realen Verbrauch live.
resources:
requests:
memory: "256Mi"
limits:
memory: "512Mi" # nach echtem Bedarf, nicht nach Bauchgefühl
3. Liveness-Probe schlägt fehl (Exit-Code 143, oft mit leeren Logs)
Die Liveness-Probe schlägt fehl, Kubelet beendet den Container mit SIGTERM. Wenn die Probe schon beim ersten Run fehlschlägt, sehen Sie meist gar keine Logs.
Klassischer Fail: initialDelaySeconds ist zu niedrig. Eine Spring-Boot-App braucht 30-60s zum Starten, die Probe feuert nach 10s und tötet den Container.
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 60 # statt 10
periodSeconds: 10
failureThreshold: 3
Diagnose:
kubectl describe pod <name> | grep -A 5 "Liveness"
kubectl get events | grep -i "liveness"
Kubernetes Debugging - systematisch statt raten
Echte Production-Incidents nachstellen, kubectl-Workflows verinnerlichen, Root-Causes in Minuten finden.
Workshop-Details ansehen4. Command not found (Exit-Code 127)
Der Container-Image hat den im Manifest angegebenen Command nicht. Oder der Pfad ist falsch:
command: ["/usr/local/bin/myapp"] # existiert das wirklich?
Schneller Test:
kubectl debug -it <pod> --image=busybox --target=<container>
# im debug container:
ls /proc/1/root/usr/local/bin/
Mit dem ephemeral debug container teilen Sie den Filesystem-Namespace und können sehen, was der Original-Container an Pfaden tatsächlich hatte.
5. ConfigMap oder Secret fehlt (Exit-Code 1, oft mit “no such file”)
Pod-Manifest mounted eine ConfigMap, die nicht existiert. Container startet, findet die Datei nicht, crasht.
kubectl get configmap -n <namespace>
kubectl get secret -n <namespace>
Häufige Ursache: Namespace-Verwechslung. Pod ist in prod, ConfigMap ist in default.
6. Falsche Permissions auf Volume (Exit-Code 1, “permission denied”)
Mounted PV hat UID/GID, die der Container-User nicht lesen darf. Tritt häufig bei Migration von Docker-Compose nach Kubernetes auf.
Fix: securityContext.fsGroup setzen, damit Kubelet beim Mount die Permissions anpasst:
spec:
securityContext:
fsGroup: 1000
containers:
- name: app
image: ...
7. Race Condition gegen Datenbank (Exit-Code 1, “connection refused”)
Die App startet vor der Datenbank, kann sich nicht verbinden, crasht. Der Restart trifft die DB jetzt vielleicht - oder nicht.
Fix: initContainer mit Wait-Skript:
initContainers:
- name: wait-for-db
image: busybox:1.36
command: ['sh', '-c', 'until nc -zv postgres 5432; do echo waiting for db; sleep 2; done']
Oder besser: Application-Level-Retry mit Exponential Backoff direkt im Code. initContainer ist das Pflaster, nicht die Lösung.
Decision Tree
Exit-Code 137 + Reason OOMKilled? → Ursache 2 (Memory)
↓ nein
Logs --previous komplett leer? → Ursache 3 (Liveness-Probe)
↓ nein
Logs zeigen "no such file"? → Ursache 5 (ConfigMap/Secret)
↓ nein
Logs zeigen "permission denied"? → Ursache 6 (Volume-Permissions)
↓ nein
Logs zeigen "command not found"? → Ursache 4 (Command/Pfad)
↓ nein
Logs zeigen "connection refused"? → Ursache 7 (Race Condition)
↓ nein
Ursache 1 (Application Error)
→ Logs gründlich lesen, ggf. Stacktrace
Was die Workshops nicht ersetzen
Dieser Workflow löst die häufigsten Fälle. Was nicht in den 7 Ursachen steckt:
- JVM-Container mit verstecktem OOM: der Java-Heap explodiert, aber Kernel sieht’s nicht als OOM. Sie sehen nur Exit-Code 1 mit
Killed. - Network-Policy blockiert Init-Egress: App will beim Start Configs vom Vault holen, NetworkPolicy lässt nur Inbound zu, App crasht ohne Log.
- Cluster-Autoscaler killt Node während Pod-Start: Pod wird vor Liveness-Probe von Node evicted, Restart auf neuem Node.
Diese Pattern brauchen mehr als Kommando-Reihenfolge - sie brauchen System-Verständnis. Genau das macht den Unterschied zwischen “raten und probieren” und “in 3 Minuten die Root Cause finden”.
Wie es weitergeht
Im Kubernetes Debugging Workshop spielen wir 8 echte Production-Incidents nach - inklusive der drei oben genannten Edge Cases - und drillen den Workflow, bis er sitzt. 1 Tag, 8 Stunden, danach lösen Sie CrashLoopBackOff systematisch und nicht durch Raten.
Bevor Sie buchen: Schauen Sie sich auch unseren kubectl Debugging Cheatsheet an - dort gibt es die 12 wichtigsten Befehle als kompletten Workflow.
Kubernetes Debugging - systematisch statt raten
Echte Production-Incidents nachstellen, kubectl-Workflows verinnerlichen, Root-Causes in Minuten finden.
Workshop-Details ansehenWeiterlesen
kubectl Debugging Cheatsheet: 12 Befehle für Production-Incidents
Strukturierter Debugging-Workflow für Kubernetes in Production: 12 kubectl-Befehle in der richtigen Reihenfolge - von Pod-Status bis ephemeral debug containers.
8 min debuggingkubectl Debugging Cheatsheet: 12 Befehle für Production-Incidents
Strukturierter Debugging-Workflow für Kubernetes in Production: 12 kubectl-Befehle in der richtigen Reihenfolge - von Pod-Status bis ephemeral debug containers.
8 minBrauchen Sie eine zweite Meinung zu Ihrem Cluster?
Buchen Sie einen kostenfreien 30-Minuten Kubernetes Health-Check. Wir schauen uns Ihr Setup an und geben konkrete Hinweise - ohne Verkaufsgespräch.
Termin buchen