Post-Mortem: Anatomy of the Cloudflare Outage (November 18, 2025)
A deep dive into the Cloudflare outage of November 18, 2025, analyzing the root cause, technical failure, and lessons learned.
Practical fixes, shipped as working code.
A deep dive into the Cloudflare outage of November 18, 2025, analyzing the root cause, technical failure, and lessons learned.
On November 18, 2025, a significant portion of the internet went dark. Major platforms like ChatGPT, Spotify, Canva, and X (formerly Twitter) became inaccessible as Cloudflare, a central pillar of internet infrastructure, suffered a critical failure.
Contrary to initial speculation, this was not a massive DDoS attack or a zero-day exploit. It was a latent bug triggered by a routine database maintenance task. This article deconstructs the technical chain of events, the specific engineering failure in the Bot Management module, and the lessons developers can learn about fault isolation and safe deployment practices.
At 11:20 UTC, Cloudflare’s core network traffic delivery began to fail. End-users across the globe started seeing HTTP 5xx errors and “Cloudflare Connection Failure” screens.
panic in the proxy service caused by a malformed (oversized) configuration file generated by the Bot Management system.The failure was a classic “perfect storm” involving three distinct layers: a database permission change, a configuration generation script, and a lack of graceful error handling in the core proxy.
Cloudflare engineers were performing a routine update on a ClickHouse database cluster used to generate “feature files” for the Bot Management system. These files contain rules and scores used to detect automated traffic.
The update involved changing permissions on the database. Crucially, this change caused a specific SQL query—responsible for fetching bot detection rules—to return duplicate rows.
The SQL query was designed to output a binary configuration file. Because of the duplicate rows returned by the database, the generated file doubled in size.
Normally, this file is propagated to thousands of servers at Cloudflare’s edge. The distribution mechanism worked as intended, pushing this new, larger file to the edge nodes.
unwrap() on ErrorThis is where the “latent bug” triggered. Cloudflare’s proxy service (likely written in Rust, given their stack and the error signature) loads this feature file into the Bot Management module.
The code responsible for parsing this file had a hard-coded limit on the file size or buffer. When the file exceeded this limit, the parser returned an Err (Error) result.
Critically, the calling code handled this result using an equivalent of .unwrap(). In Rust, calling unwrap() on an error result causes the thread to panic (crash) immediately. Because this module runs within the critical path of the main proxy process, the entire proxy service crashed and restarted.
The Developer Takeaway: A crash in a non-critical subsystem (Bot Management configuration loading) should never bring down the entire critical path (Core Traffic Proxy). This highlights the importance of fault isolation.
One of the most confusing aspects of this outage for external observers was the “saw-tooth” pattern of availability. Services would go down, come back up for a few minutes, and then crash again.
Why this happened:
This created a loop of destruction that made diagnosing the issue incredibly difficult, as the system appeared to “fix itself” repeatedly.
The incident response followed a high-pressure trajectory:
Timeline to Recovery:
unwrap() in Production: In languages like Rust, use match or if let to handle errors gracefully. If a configuration file fails to load, the system should fall back to the last known good configuration or disable that specific module—not crash the application.