7 echte Produktionsausfälle mit Claude Code: Vollständige Wiederherstellung mit RCA & Prävention
7 echte Produktionsvorfälle mit Claude Code: API-Key-Leaks, DB-Löschungen, Kostenexplosionen und Serviceausfälle – mit Ursachenanalyse und Präventionsstrategien.
„Claude Code ist praktisch, aber ich habe Angst, es in der Produktion einzusetzen” – viele Entwickler teilen dieses Gefühl. Und dieser Instinkt ist berechtigt.
Claude Code operiert auf Ihrem Dateisystem und Ihrer Shell mit höheren Rechten als eine normale IDE. Gleichzeitig führt das wiederholte Klicken auf die Bestätigungsschaltfläche dazu, dass die Wachsamkeit nachlässt – eine bekannte menschliche Schwäche. Wenn diese beiden Faktoren zusammentreffen, kommt es zu Produktionsausfällen.
Dieser Artikel dokumentiert 7 echte Produktionsvorfälle mit Claude Code – komplett mit Ursachen, Schadensumfang, Wiederherstellungsverfahren, RCA (Root Cause Analysis) und Präventionsstrategien. Lesen Sie dies, bevor ein Unfall in Ihrer Organisation passiert.
Vorfall 1: API-Key-Leak → 2.800 € unberechtigte Gebühren
Zeitverlauf
09:12 Claude Code angewiesen: ".env committen, um Umgebungsvariablen an CI zu übergeben"
09:13 git add .env && git push wurde ohne Bestätigung ausgeführt (Allow-Liste zu permissiv)
09:14 GitHub Secret Scanning erkannte es, E-Mail-Benachrichtigung gesendet
09:31 AWS-Crawler erkannte den OpenAI-Key, unberechtigte Nutzung begann
11:00 Gebühr von 2.800 € im OpenAI-Dashboard bestätigt
Wiederherstellungsverfahren
# Schritt 1: API-Key sofort sperren (höchste Priorität – innerhalb von 5 Minuten)
# → Key im Dashboard von OpenAI / jeweiligem Dienst widerrufen
# Schritt 2: .env vollständig aus der Git-History entfernen
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch .env" \
--prune-empty --tag-name-filter cat -- --all
# Schritt 3: Alle Branches force pushen
git push origin --force --all
git push origin --force --tags
# Schritt 4: Zu .gitignore hinzufügen, um Wiederholung zu verhindern
echo ".env" >> .gitignore
git add .gitignore && git commit -m "security: add .env to gitignore"
# Schritt 5: Neuen API-Key ausstellen und in .env eintragen
RCA
- Direkte Ursache:
settings.jsonhatteBash(git add*)in derallow-Liste, was die Ausführung ohne Bestätigung ermöglichte - Grundursache: Sicherheitskonfiguration wurde zugunsten von Produktcode zurückgestellt
Prävention
// .claude/settings.json
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash(git add*)",
"hooks": [{
"type": "command",
"command": "git diff --cached --name-only | grep -E '\\.env' && echo '🚨 .env erkannt! Abbruch.' && exit 1 || exit 0"
}]
}]
}
}
Vorfall 2: rm -rf löschte das gesamte Projekt
Zeitverlauf
14:33 Anweisung: "node_modules bereinigen und neu installieren"
14:33 Claude Code führte rm -rf node_modules aus (bis hier normal)
14:34 Folgebefehl "alte Build-Dateien auch löschen" → rm -rf dist/ ausgeführt
14:34 Pfad-Fehlinterpretation: rm -rf dist /src wurde ausgeführt (Leerzeichen als Trennzeichen)
14:35 src/-Verzeichnis vollständig gelöscht. Auch Konfigurationsdateien außerhalb von Git verschwunden
14:40 git checkout . stellte getrackte Dateien wieder her, aber .env und lokale Configs dauerhaft verloren
Wiederherstellungsverfahren
# Von Git getrackte Dateien können wiederhergestellt werden
git checkout .
git clean -fd # Überflüssige Dateien entfernen
# Gelöschte Dateien in git stash oder reflog suchen
git stash list
git reflog
# Nicht von Git verwaltete Dateien (.env etc.) aus Backup wiederherstellen
# → Ohne Backup muss alles neu konfiguriert werden
RCA
- Direkte Ursache: Pfad mit Leerzeichen wurde nicht korrekt in Anführungszeichen gesetzt, was zu
rm -rf dist /srcführte - Grundursache:
rm -rfstand inallowstattask
Prävention
{
"permissions": {
"deny": ["Bash(rm -rf ~*)", "Bash(rm -rf /*)"],
"ask": ["Bash(rm*)"]
},
"hooks": {
"PreToolUse": [{
"matcher": "Bash(rm*)",
"hooks": [{
"type": "command",
"command": "echo '⚠️ Löschbefehl erkannt. Ziel: $CLAUDE_TOOL_INPUT_COMMAND\nAusführung in 5 Sekunden. Abbruch mit Ctrl+C.' && sleep 5"
}]
}]
}
}
Vorfall 3: git push --force löschte Commits von 3 Kollegen
Zeitverlauf
16:00 Anweisung: "Es gibt einen Konflikt mit Remote. Lokale Änderungen priorisieren und überschreiben"
16:01 git push --force origin main wurde ausgeführt
16:01 ~200 Codezeilen, die 3 Kollegen an diesem Tag committed hatten, wurden gelöscht
16:10 Kollege A im Slack: "Seltsam, meine Commits sind weg"
16:15 Ursache identifiziert. Kollegen A/B hatten lokale Kopien, aber Kollege C hatte bereits gelöscht – dauerhaft verloren
Wiederherstellungsverfahren
# Verlorene Commits im reflog suchen (auf der Maschine, die den Push ausgeführt hat)
git reflog | head -30
# → Beispiel: abc1234 HEAD@{3}: Commit vor dem --force-Push
# Verlorene Commits wiederherstellen
git checkout -b recovery abc1234
git push origin recovery
# In main mergen und aufräumen
git checkout main
git merge recovery --no-ff
git push origin main
RCA
- Direkte Ursache: Die Absicht, einen Konflikt zu lösen, wurde als
--forcestatt--force-with-leaseinterpretiert - Grundursache: Force Push auf den main-Branch war nicht in der
deny-Liste
Prävention
{
"permissions": {
"deny": [
"Bash(git push --force *main*)",
"Bash(git push --force *master*)",
"Bash(git push -f *main*)"
]
}
}
<!-- CLAUDE.md -->
## Git-Regeln
- `git push --force` ist verboten
- Für Konfliktlösung `git push --force-with-lease` verwenden
- Push auf main/master immer erst nach Benutzerbestätigung
Vorfall 4: Fehlgeschlagene DB-Migration löschte 40.000 Produktionsdatensätze
Zeitverlauf
10:00 Anweisung: "Migration ausführen, um phone_number-Spalte zur users-Tabelle hinzuzufügen"
10:01 Claude Code generierte und führte das Migrationsskript aus
10:01 Ein Bug im Skript führte dazu, dass die Rückwärtsmigration (mit DROP COLUMN) ausgeführt wurde
10:02 users.email-Spalte (NOT NULL) wurde aus der Produktion gelöscht
10:02 Alle APIs gaben 500-Fehler zurück, Service vollständig ausgefallen
10:05 Vorfall erkannt, Ursachenermittlung begann
10:30 Wiederherstellung aus Snapshot vom Vortag (ein Tag Datenverlust)
Wiederherstellungsverfahren
# 1. Service sofort in den Wartungsmodus versetzen
# nginx: return 503; oder Vercel: Wartungsseite
# 2. Aktuellen DB-Zustand prüfen
psql $DATABASE_URL -c "\d users"
# 3. Aus Backup wiederherstellen (für RDS)
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier mydb \
--target-db-instance-identifier mydb-restored \
--restore-time 2026-04-17T23:00:00Z
# 4. Falls Spalte noch vorhanden, manuell hinzufügen
ALTER TABLE users ADD COLUMN email VARCHAR(255);
UPDATE users SET email = '(Wiederherstellung erforderlich)' WHERE email IS NULL;
# 5. Service wiederherstellen
RCA
- Direkte Ursache: Der Migrationsskript-Generator verwechselte Up- und Down-Migration
- Grundursache: Die Migration wurde ohne Test in einer Staging-Umgebung direkt in der Produktion ausgeführt
Prävention
<!-- CLAUDE.md -->
## Pflichtregeln für DB-Migrationen
1. Immer in der Staging-Umgebung testen, bevor die Produktion betroffen wird
2. Immer manuelles Backup vor der Migration erstellen:
pg_dump $DATABASE_URL > backup_$(date +%Y%m%d_%H%M%S).sql
3. Skripte mit DROP COLUMN / TRUNCATE / DELETE (ohne WHERE) müssen
immer vom Benutzer bestätigt werden, bevor sie ausgeführt werden
4. Bei Verwendung der Produktions-DATABASE_URL vor der Ausführung anzeigen: 'Schreibe in PRODUKTIONS-DB. Fortfahren?'
Vorfall 5: Unendliche API-Aufrufe erzeugten über Nacht 750 € Kosten
Zeitverlauf
23:00 Anweisung: "Bei Fehlern automatisch wiederholen" und Stapelverarbeitung gestartet
23:01 Externe API begann, 503 zurückzugeben
23:01 Wiederholungslogik lief ohne Limit, traf die API jede Sekunde
07:00 Am nächsten Morgen Benachrichtigung von Anthropic: "Nutzung nähert sich dem Limit"
07:05 28.000 API-Aufrufe und 750 € Kosten festgestellt
Wiederherstellungsverfahren
# 1. Prozess sofort stoppen
pkill -f "node batch-process.js"
# 2. Kosten prüfen und Anthropic-Support kontaktieren
# → Aufrichtige Kommunikation kann zu teilweiser Rückerstattung führen
# 3. Nutzungswarnungen einrichten
# Anthropic-Konsole → Usage Limits → Monatliches Budget-Alert setzen
Prävention
// utils/retry.ts — immer dieses Utility verwenden
export async function withRetry<T>(
fn: () => Promise<T>,
{ maxAttempts = 3, baseDelayMs = 1000, maxDelayMs = 30000 } = {}
): Promise<T> {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (err) {
if (attempt === maxAttempts) throw err;
const delay = Math.min(
baseDelayMs * 2 ** (attempt - 1) + Math.random() * 500,
maxDelayMs
);
console.warn(`Retry ${attempt}/${maxAttempts} in ${Math.round(delay)}ms`);
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error("unreachable");
}
<!-- CLAUDE.md -->
## Regeln für API-Aufrufe
- Maximal 3 Wiederholungsversuche mit exponentiellem Backoff erforderlich
- while(true) + API-Aufrufe sind streng verboten
- Stapeljobs müssen explizite Mengenlimits haben
- Vor der Produktionsausführung --dry-run Smoke-Test durchführen
Vorfall 6: Defekte Abhängigkeiten nach Deployment legten den Service lahm
Zeitverlauf
15:00 Anweisung: "Pakete auf die neuesten Versionen aktualisieren"
15:01 npm update ausgeführt, package-lock.json änderte sich erheblich
15:05 Lokaler Build erfolgreich
15:10 In Produktion deployt
15:12 Major-Version-Inkompatibilität in Produktionsabhängigkeiten, Start fehlgeschlagen
15:12 503-Fehler, Service vollständig ausgefallen
15:30 Rollback auf vorherige Version abgeschlossen
Wiederherstellungsverfahren
# Bei Vercel / Cloudflare Pages: vorheriges Deployment sofort reaktivieren
# → Ein-Klick-Rollback über das Dashboard
# Code mit git revert zurücksetzen
git revert HEAD~1
git push
# package-lock.json auf vorherige Version zurücksetzen
git checkout HEAD~1 -- package-lock.json
npm ci # Verwendet streng die package-lock.json
RCA
- Direkte Ursache:
npm updateaktualisierte eine Major-Version, was zu einem Breaking Change führte - Grundursache: Deployment-Überprüfung in der Staging-Umgebung wurde übersprungen
Prävention
<!-- CLAUDE.md -->
## Paketverwaltungsregeln
- npm update ist verboten (npm update --save-dev bedingt erlaubt)
- Major-Version-Upgrades von Paketen erfordern Benutzerbestätigung
- Vor dem Deployment immer Verhalten in Staging überprüfen
- Nach dem Produktions-Deployment 5 Minuten lang Fehlerprotokolle überwachen
Vorfall 7: Fehlkonfigurierte Berechtigungen machten alle Nutzerdaten öffentlich zugänglich
Zeitverlauf
11:00 Anweisung: "Benutzerliste zum Admin-Panel-API-Endpunkt hinzufügen"
11:05 /api/admin/users ohne Authentifizierungsprüfung implementiert
11:10 In Produktion deployt
11:10 Personenbezogene Daten aller Benutzer für jeden zugänglich
13:30 Sicherheits-Audit-Tool erkannte nicht authentifizierten Endpunkt
13:35 Endpunkt sofort deaktiviert
Wiederherstellungsverfahren
# 1. Betroffenen Endpunkt sofort deaktivieren
# nginx: location /api/admin { return 403; }
# 2. Zugriffsprotokolle prüfen, um den Umfang der Exposition zu bestimmen
grep "/api/admin/users" /var/log/nginx/access.log | \
awk '{print $1}' | sort | uniq -c | sort -rn
# 3. Betroffene Benutzer benachrichtigen (DSGVO-Anforderungen prüfen)
# 4. Authentifizierungs-Middleware hinzufügen und neu deployen
RCA
- Direkte Ursache: Die Anweisung „zum Admin-Panel hinzufügen” vermittelte keine Authentifizierungsanforderungen
- Grundursache: Sicherheitsanforderungen waren nicht in CLAUDE.md dokumentiert
Prävention
<!-- CLAUDE.md -->
## API-Sicherheitsanforderungen
- /api/admin/*-Endpunkte müssen immer Admin-Authentifizierung implementieren
- /api/user/*-Endpunkte müssen immer Login-Authentifizierung implementieren
- Nur /api/public/*-Endpunkte sind ohne Authentifizierung zugänglich
- Beim Hinzufügen einer neuen API die erforderliche Authentifizierungsebene kommentieren
Gemeinsamer Incident-Response-Ablauf (Postmortem-Vorlage)
# Postmortem: [Vorfallstitel]
## Zusammenfassung
- Eingetreten um: YYYY-MM-DD HH:MM
- Erkannt um: YYYY-MM-DD HH:MM
- Behoben um: YYYY-MM-DD HH:MM
- Auswirkung: (Anzahl der Benutzer / Funktionen / Dauer)
- Schweregrad: P0/P1/P2/P3
## Zeitverlauf
| Zeit | Ereignis |
|-------|----------|
| HH:MM | Vorfall eingetreten |
| HH:MM | Erkannt |
| HH:MM | Reaktion begann |
| HH:MM | Grundursache identifiziert |
| HH:MM | Wiederherstellung abgeschlossen |
## Grundursache
- Direkte Ursache:
- Grundursache:
- Verschlimmernde Ursache:
## Präventionsmaßnahmen
| Maßnahme | Verantwortlicher | Frist |
|----------|-----------------|-------|
| | | |
## Erkenntnisse
Zusammenfassung: Mindestkonfiguration zur Vorfalleprävention
// Jetzt kopieren und in .claude/settings.json einfügen
{
"permissions": {
"deny": [
"Bash(rm -rf ~*)",
"Bash(rm -rf /*)",
"Bash(git push --force *main*)",
"Bash(git push --force *master*)",
"Bash(git push -f *main*)",
"Bash(DROP TABLE*)",
"Bash(TRUNCATE *)",
"Bash(curl * | bash)",
"Bash(wget * | sh)"
],
"ask": [
"Write(**)", "Edit(**)",
"Bash(rm*)", "Bash(git commit*)",
"Bash(git push*)", "Bash(*deploy*)",
"Bash(npm install*)", "Bash(*migrate*)"
]
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash(git add*)",
"hooks": [{ "type": "command",
"command": "git diff --cached --name-only | grep '\\.env' && echo '🚨 .env erkannt! Abbruch.' && exit 1 || exit 0" }]
},
{
"matcher": "Bash(rm*)",
"hooks": [{ "type": "command",
"command": "echo '⚠️ Löschbefehl erkannt. Ausführung in 5 Sekunden. Abbruch mit Ctrl+C.' && sleep 5" }]
}
]
}
}
Produktionsausfälle entstehen, wenn man die 30 Minuten für die Konfiguration einspart. Alle 7 Vorfälle in diesem Artikel hätten mit einer ordentlichen settings.json und CLAUDE.md verhindert werden können.
Verwandte Artikel
- Vollständiger Leitfaden für Claude Code Sicherheits-Best-Practices
- 7 Claude Code Sicherheitsfehler-Fallbeispiele
- Vollständiger Leitfaden für Claude Code Berechtigungen
Referenzen
Bring deinen Claude-Code-Workflow aufs nächste Level
50 in der Praxis erprobte Prompt-Vorlagen zum direkten Copy-and-paste in Claude Code.
Kostenloses PDF: Claude-Code-Spickzettel in 5 Minuten
Trag einfach deine E-Mail-Adresse ein – wir senden dir den A4-Spickzettel als PDF sofort zu.
Wir behandeln deine Daten sorgfältig und senden niemals Spam.
Über den Autor
Masa
Ingenieur, der Claude Code intensiv nutzt. Betreibt claudecode-lab.com, ein Tech-Medium in 10 Sprachen mit über 2.000 Seiten.
Ähnliche Artikel
Claude Code API-Kosten meistern: 5 Techniken, die die Rechnung von $450 auf $45/Monat senken
Echte Zahlen zu Claude Code API-Preisen. So wurde durch Prompt-Caching, Modelloptimierung und Batching eine Kostenreduktion von 90 % erreicht – von $450 auf $45 pro Monat.
10 gefährliche Prompt-Muster in Claude Code | Was Sie vermeiden sollten und sichere Alternativen
10 gefährliche Prompt-Muster, die Sie Claude Code niemals geben sollten. Erfahren Sie, wie vage Anweisungen zu Codeverlust, DB-Zerstörung, explodierenden Kosten und Schlüssellecks führen.
Claude Code Sicherheits-Best-Practices: API-Schlüssel, Berechtigungen & Produktionsschutz
Ein praxisorientierter Sicherheitsleitfaden für den sicheren Einsatz von Claude Code. Von API-Schlüsselverwaltung über Berechtigungseinstellungen bis hin zu Hook-Automatisierung und Produktionsschutz — mit funktionierenden Codebeispielen.