Postmortem zur Cloudflare-Störung vom 18. November 2025
(blog.cloudflare.com)- Am 18. November 2025 um 11:20 Uhr (UTC) fiel eine zentrale Funktion zur Weiterleitung von Traffic im Cloudflare-Netzwerk aus, sodass Nutzer weltweit Fehlerseiten sahen
- Die Ursache war, dass durch eine Änderung der Datenbankberechtigungen die „Feature-Datei“ des Bot-Management-Systems ungewöhnlich groß wurde; ein Cyberangriff stand nicht dahinter
- Durch das Wachstum dieser Datei überschritt die Traffic-Routing-Software ihren Grenzwert und schlug fehl, was in großem Umfang HTTP-5xx-Fehler auslöste
- Gegen 14:30 Uhr wurde die Verteilung der problematischen Datei gestoppt und durch die zuvor funktionierende Version ersetzt, wodurch der zentrale Traffic wiederhergestellt wurde; um 17:06 Uhr liefen alle Dienste wieder normal
- Cloudflare bewertet den Vorfall als die schlimmste Störung seit 2019 und treibt Maßnahmen zur Vermeidung einer Wiederholung voran, darunter strengere Validierung von Konfigurationsdateien und die Einführung eines globalen Kill Switches
Überblick über die Störung
- Gegen 11:20 Uhr kam es im Cloudflare-Netzwerk zu einem Ausfall der zentralen Traffic-Weiterleitung, Nutzer bekamen interne Fehlerseiten von Cloudflare angezeigt
- Ein Cyberangriff oder böswilliges Verhalten war nicht die Ursache; der direkte Auslöser war eine Änderung der Berechtigungen im Datenbanksystem
- Durch diese Änderung verdoppelte sich die Größe der vom Bot-Management-System verwendeten „Feature-Datei“, die im gesamten Netzwerk verteilt wurde
- Beim Einlesen dieser Datei überschritt die Traffic-Routing-Software die Grenze für die Dateigröße, was zu Systemfehlern führte
- Zunächst wurde fälschlich von einem großangelegten DDoS-Angriff ausgegangen, nach der Ursachenanalyse wurde jedoch die zuvor funktionierende Datei wieder eingespielt und die Wiederherstellung eingeleitet
Verlauf und Auswirkungen der Störung
- Vor 11:20 lag die Quote der 5xx-Fehler im Normalbereich, danach stieg sie durch die Verteilung der fehlerhaften Feature-Datei sprunghaft an
- Auf einigen Knoten des ClickHouse-Datenbankclusters wurden alle 5 Minuten fehlerhafte Abfrageergebnisse erzeugt; da abwechselnd normale und fehlerhafte Dateien verteilt wurden, geriet das System in einen Zyklus aus wiederholter Erholung und erneutem Ausfall
- Ab 14:30 wurde die Erzeugung der problematischen Datei gestoppt und eine funktionierende Datei manuell eingefügt, danach erfolgte die Wiederherstellung durch Neustarts der Core-Proxys
- Um 17:06 Uhr liefen alle Dienste wieder normal
| Dienst | Auswirkung |
|---|---|
| Core CDN und Sicherheitsdienste | HTTP-5xx-Fehler |
| Turnstile | Laden fehlgeschlagen, Login nicht möglich |
| Workers KV | Starker Anstieg von 5xx-Fehlern durch Gateway-Ausfall |
| Dashboard | Login wegen Turnstile-Störung nicht möglich |
| Email Security | Vorübergehend geringere Genauigkeit bei der Spam-Erkennung, einige automatische Verschiebungen fehlgeschlagen |
| Access | Viele Authentifizierungsfehler, bestehende Sitzungen blieben erhalten |
- Während der Störung stieg auch die CDN-Antwortlatenz, verursacht durch einen sprunghaften Anstieg der CPU-Auslastung im Debugging-System
Ursache der Störung: Bot-Management-System
- Das Bot-Management-Modul von Cloudflare verwendet Machine-Learning-Modelle, um pro Anfrage einen Bot-Score zu erzeugen
- Die als Modelleingabe verwendete Feature-Konfigurationsdatei wird alle paar Minuten im gesamten Netzwerk verteilt, um auf aktuelle Bedrohungen zu reagieren
- Durch eine Änderung im Verhalten einer ClickHouse-Abfrage wurden zahlreiche doppelte Feature-Zeilen eingefügt, wodurch die Datei anwuchs
- Dadurch verursachte das Bot-Management-Modul Fehler und lieferte HTTP-5xx-Antworten zurück, was sich auch auf Workers KV und Access auswirkte
- In der neuen Proxy-Engine FL2 führte dies zu 5xx-Fehlern, in der älteren Version FL wurde der Bot-Score auf 0 gesetzt, was zu mehr Fehlklassifizierungen führte
Änderung im Verhalten der ClickHouse-Abfrage
- Um 11:05 Uhr wurde eine Änderung der Datenbankzugriffsrechte in ClickHouse ausgerollt
- Zuvor konnte nur auf Metadaten der Datenbank
defaultzugegriffen werden, nach der Änderung wurden auch Metadaten der Datenbankr0sichtbar - Die Abfrage zur Erzeugung der Feature-Datei im Bot Management wurde ohne Filter auf den Datenbanknamen ausgeführt, wodurch es letztlich zu doppelt zurückgegebenen Spalten kam
- Dadurch stieg die Zahl der Zeilen in der Feature-Datei auf mehr als das Doppelte und überschritt die Systemgrenzen
Speicher-Vorallokation und System-Panic
- Das Bot-Management-Modul reserviert Speicher vorab und setzt dabei ein Maximum von 200 Machine-Learning-Features
- Da die fehlerhafte Datei mehr als 200 Features enthielt, kam es im Rust-Code zu einer Panic, mit der Fehlermeldung
thread fl2_worker_thread panicked: called Result::unwrap() on an Err value - Dadurch kam es zu einem massiven Auftreten von HTTP-5xx-Fehlern
Weitere Auswirkungen und Wiederherstellung
- Da Workers KV und Access vom Core-Proxy abhängen, weitete sich die Störung aus
- Um 13:04 Uhr wurde für Workers KV ein Patch ausgerollt, damit der Proxy umgangen wird, wodurch die Fehlerrate sank
- Das Dashboard war wegen der Abhängigkeit von Turnstile und Workers KV nicht nutzbar
- Zweimal verringerte sich die Verfügbarkeit: von 11:30 bis 13:10 sowie von 14:40 bis 15:30
- Durch Rückstau und Wiederholungsanfragen stieg die Latenz, gegen 15:30 war die Wiederherstellung erreicht
- Nach 14:30 liefen die meisten Dienste wieder normal, um 17:06 war die vollständige Wiederherstellung abgeschlossen
Maßnahmen zur Vermeidung einer Wiederholung
- Stärkere Validierung der Eingaben für von Cloudflare erzeugte Konfigurationsdateien
- Ausbau eines globalen Kill Switches für Funktionen
- Verhinderung von Ressourcenerschöpfung durch Fehlerberichte
- Überprüfung von Fehlerbedingungen in sämtlichen Core-Proxy-Modulen
Zusammenfassung der Timeline (UTC)
| Uhrzeit | Status | Beschreibung |
|---|---|---|
| 11:05 | Normal | Änderung der Datenbankzugriffskontrolle ausgerollt |
| 11:28 | Beginn der Auswirkungen | Erster Fehler im Kundentraffic |
| 11:32–13:05 | Untersuchung läuft | Analyse der Ursache der Workers-KV-Fehler, Versuche zur Abschwächung |
| 13:05 | Auswirkungen reduziert | Umgehung für Workers KV und Access angewendet |
| 13:37 | Fokus auf Wiederherstellung | Rollback der Bot-Management-Konfigurationsdatei wird vorbereitet |
| 14:24 | Verteilung der problematischen Datei gestoppt | Test der funktionierenden Datei abgeschlossen |
| 14:30 | Größter Teil der Auswirkungen behoben | Funktionierende Datei global verteilt, Wiederherstellung der Dienste beginnt |
| 17:06 | Vollständig wiederhergestellt | Alle Dienste wieder normal |
Fazit
- Diese Störung entstand durch das Zusammenspiel der Logik zur Erzeugung der Bot-Management-Konfigurationsdatei und einer Änderung der Datenbankberechtigungen
- Cloudflare bewertet dies als die schwerwiegendste Netzwerkstörung seit 2019
- Künftig sollen strukturelle Verbesserungen und stärkere automatisierte Schutzmechanismen die Resilienz des Systems erhöhen
8 Kommentare
Ausfälle im Zusammenhang mit Konfigurationsdateien treten offenbar überall auf.
Als Cloudflare ausfiel und dadurch alle möglichen Dienste unterbrochen wurden, war das die Hölle..
Das Dokument zur Ursachenanalyse wurde ziemlich schnell veröffentlicht, wow.
Übrigens war der Autor dieses Artikels der CEO.
Hacker-News-Kommentare
Das ist eine
.unwrap()-Panne im Wert von mehreren Millionen DollarAuf einem Pfad der zentralen Internet-Infrastruktur
.unwrap()aufzurufen, kommt einer Erklärung gleich: „Das kann niemals fehlschlagen; wenn doch, wird der Thread sofort beendet.“Der Rust-Compiler erzwingt, dass die Möglichkeit eines Fehlschlags explizit ausgedrückt wird, aber hier wurde statt einer sauberen Behandlung ein Panic gewählt.
Ich halte das für ein typisches Beispiel des Antipatterns „parse, don’t validate“.
.unwrap()einen blinden Fleck zu haben. Vielleicht, weil es in Beispielcode so oft auftaucht.In echtem Produktivcode sollten
.unwrap()oder.expect()wie ein Panic im Review behandelt werden.Wenn man in Produktionscode
.unwrap()verwendet, sollte man zwingend einen „INFALLIBILITY“-Kommentar hinzufügen; mitclippy::unwrap_usedlässt sich das auch erzwingen.Nicht einfach nur wegen
.unwrap(), sondern weil die Query die Datenbanken nicht unterschied, dadurch der Payload größer wurde und ClickHouse mehr DBs offengelegt hat.Statt vorschnell zu sagen „es lag an unwrap“, halte ich Designverbesserungen für wichtiger, etwa ein globaler Kill Switch oder Mechanismen, die verhindern, dass Systemressourcen überlastet werden.
Auf der FL2-Ebene sollte man die Panics der einzelnen Komponenten abfangen, aber fail-open ist nicht immer die bessere Wahl.
Man sollte Logik ergänzen, damit auf FL2-Ebene explizit entschieden wird, ob ein Panic abgefangen und behandelt werden soll.
Bei einem geshardeten System frage ich mich außerdem, warum es kein schrittweises Rollout und Monitoring gab.
!-Unwrapping und explizites?-Unwrapping.Ich verwende implizites Unwrapping fast nie. Selbst bei garantierten Werten gehe ich immer explizit damit um.
Zum Beispiel definiere ich lieber
@IBOutlet weak var someView?statt@IBOutlet weak var someView!.Das ist eine Art belt-and-suspenders-Ansatz.
Dass sie nicht einmal 24 Stunden nach dem Ausfall bereits ein Postmortem veröffentlicht haben, ist wirklich beeindruckend.
In den meisten Großunternehmen wäre eine Veröffentlichung des Codes wegen der Prüfung durch diverse Stakeholder fast unmöglich.
Beim Lesen von Cloudflares Erklärung des Ausfalls habe ich mich gefragt: „Warum hat die Wiederherstellung so lange gedauert?“
Die Ursache des Ausfalls habe ich verstanden, aber wenn der Großteil des Netzwerks ausgefallen ist, sollte die jüngste Konfigurationsänderung zurückzunehmen doch Priorität 1 sein, oder?
Natürlich ist das im Nachhinein klar, aber dass die Untersuchung bereits nach 7 Minuten begonnen hat, ist beeindruckend.
Dieser Vorfall wirkt ähnlich wie der CrowdStrike-Zwischenfall.
Eine automatisch erzeugte Konfigurationsdatei hat die Software beschädigt und wurde über das gesamte Netzwerk verteilt.
Ich verstehe, dass schnelle Deployments nötig sind, aber dieser Fall zeigt das Fehlen einer Strategie für schrittweise Rollouts und Rollbacks.
Wenn man sich die von Cloudflare angekündigten künftigen Verbesserungen ansieht, gibt es unter anderem
Doch Canary-Deployments oder schrittweise Konfigurations-Rollouts fehlen.
Ein globaler Schalter kann riskant sein und durch einen einzigen Bug das gesamte System stoppen.
Ich frage mich auch, warum ClickHouse als Feature-Flag-Store verwendet wurde. Selbst in der ClickHouse-Dokumentation zur Deduplizierung werden Risiken erwähnt.
Mit einem Mapping von Abhängigkeiten zwischen den Services wäre die Ursachenanalyse deutlich einfacher.
Code-Deployments erfolgen vorsichtig, Konfigurations-Deployments aber nicht. Man braucht das Bewusstsein, dass auch Konfiguration Code ist.
Interessant ist die Stelle, dass die Statusseite ausgefallen sei und man es deshalb für einen Angriff hielt.
Es heißt, sie sei vollständig von der Cloudflare-Infrastruktur getrennt, aber es gibt keine Erklärung, warum sie trotzdem mit ausgefallen ist.
Ich habe Turnstile mit einer fail-open-Strategie integriert, und das hat sich bei diesem Ausfall ausgezahlt.
Wenn das JS nicht geladen wird, erlaube ich die Übermittlung mit einem Dummy-Token, und selbst wenn die Verifizierung im Backend fehlschlägt, behandle ich es als fail-open.
Einige Nutzer wurden zwar weiterhin blockiert, aber die Gesamtauswirkungen wurden reduziert.
Dieser Ansatz ist möglich, weil es noch andere Bot-Mitigationsmaßnahmen gibt.
Das dürfte aber wohl nur funktionieren, wenn es sich nicht um einen gezielten Angriff handelt.
Ich frage mich, warum im Cloudflare-Code überhaupt
.unwrap()erlaubt wurde.Mindestens
expect("Das kann niemals passieren")hätte man verwenden sollen.Die Philosophie, Fehler als Werte zu behandeln, soll genau solche Probleme verhindern und hätte die Diagnose deutlich erleichtert.
In Code mit Netzwerkaufrufen gibt es einfach zu viele mögliche Fehlerquellen.
Während der Entwicklung benutze ich
.unwrap(), aber in Produktionscode lasse ich manchmalexpect()stehen. Es gibt Situationen, in denen man schlicht nicht sinnvoll weiterlaufen kann.Die eigentliche Lehre ist, dass zu viele Funktionen von zu wenigen Akteuren abhängen.
Die Winner-takes-all-Struktur verschärft sich, und die Resilienz des Systems nimmt ab.
Natürlich haben sie ihre Stellung durch Leistung erreicht, aber zu erwarten, dass das Internet immer „einfach funktioniert“, scheint mir überzogen.
Die Aussage „Mit Rust ist alles sicher“ ist übertrieben.
In jeder Sprache gilt: Wer sie falsch benutzt, richtet die Waffe auf den eigenen Fuß.
Sogar ein Unternehmen auf dem Niveau von CF benutzt
.unwrap()Wie hat es dieser Code überhaupt in die Produktion geschafft?
Ich glaube nicht, dass
unwrapdas Problem ist.Das grundlegende Problem ist die fehlerhafte Query.
Aber ich finde, dass es auch ein Problem war, die Prüfung des Problems mit
unwrapzu überspringen.Selbst wenn intern ein Problem entstanden wäre, wäre der Traffic wohl nicht ausgefallen, wenn man den Fehler behandelt hätte.