- 2025年11月18日11時20分(UTC)に、Cloudflareネットワークの中核的なトラフィック配信機能が停止し、世界中のユーザーにエラーページが表示された
- 原因は、データベース権限の変更により Bot Management システムの「featureファイル」が異常に肥大化したことであり、サイバー攻撃とは無関係
- このファイルサイズの増加により、トラフィックルーティングソフトウェアが上限を超えて失敗し、大規模な HTTP 5xx エラーが発生
- 14時30分ごろに問題のファイルの配布を停止し、以前の正常バージョンに置き換えて中核トラフィックを復旧、17時6分にすべてのサービスが正常化
- Cloudflare は今回の事態を2019年以降で最悪の障害と評価し、設定ファイルの検証強化やグローバル kill switch の導入など、再発防止策を進めている
障害の概要
- 11時20分ごろ、Cloudflare ネットワークで中核的なトラフィック配信の失敗が発生し、ユーザーには Cloudflare の内部エラーページが表示された
- サイバー攻撃や悪意ある行為が原因ではなく、データベースシステムの権限変更が直接の原因だった
- この変更により、Bot Management システムが使用する**「featureファイル」のサイズが2倍に増加**し、ネットワーク全体に配布された
- トラフィックルーティングソフトウェアがこのファイルを読み込む過程でファイルサイズ制限を超過し、システムエラーが発生
- 当初は大規模な DDoS 攻撃と誤認されたが、原因特定後に以前の正常なファイルへ置き換えて復旧を進めた
障害の進行と影響
- 11:20以前は 5xx エラー率は通常水準だったが、その後誤った featureファイルの配布によりエラーが急増
- ClickHouse データベースクラスタの一部ノードで誤ったクエリ結果が5分間隔で生成され、正常・異常ファイルが交互に配布されたことで、システムは復旧と失敗を繰り返した
- 14:30から問題ファイルの生成を停止し、正常ファイルを手動で挿入、コアプロキシの再起動で復旧
- 17:06にすべてのサービスが正常化
| サービス |
影響内容 |
| Core CDN およびセキュリティサービス |
HTTP 5xx エラーが発生 |
| Turnstile |
ロード失敗、ログイン不可 |
| Workers KV |
ゲートウェイ障害により 5xx エラーが急増 |
| Dashboard |
Turnstile 障害によりログイン不可 |
| Email Security |
スパム検知精度が一時的に低下、一部の自動移動に失敗 |
| Access |
認証失敗が多数発生、既存セッションは維持 |
- 障害期間中はCDN 応答遅延が増加し、デバッグシステムの CPU 使用率急増が原因だった
障害原因: Bot Management システム
- Cloudflare のBot Management モジュールは、機械学習モデルを使ってリクエストごとのボットスコアを生成
- モデル入力として使われるfeature設定ファイルは数分ごとにネットワーク全体へ配布され、最新の脅威に対応している
- ClickHouse クエリ動作の変更により重複した feature 行が多数含まれ、ファイルサイズが増加
- これにより Bot Management モジュールがエラーを起こしてHTTP 5xx レスポンスを返し、Workers KV と Access にも影響した
- 新しいプロキシエンジンFL2では 5xx エラーが発生し、旧バージョンのFLではボットスコアが 0 に設定されて誤検知が増加した
ClickHouse クエリ動作の変更
- 11:05に ClickHouse のデータベースアクセス権限変更をデプロイ
- 以前は
default データベースのメタデータのみ参照可能だったが、変更後は r0 データベースのメタデータも公開された
- Bot Management の featureファイル生成クエリがデータベース名のフィルタなしで実行され、結果として重複カラムを返却
- これにより featureファイルの行数が2倍以上に増え、システム上限を超過
メモリ事前割り当てとシステムパニック
- Bot Management モジュールは最大200個の機械学習 feature 制限を前提にメモリを事前割り当てしていた
- 誤ったファイルに 200 個を超える feature が含まれたことでRust コードで panic が発生し、
thread fl2_worker_thread panicked: called Result::unwrap() on an Err value エラーを出力
- この結果、HTTP 5xx エラーが大量発生
その他の影響と復旧過程
- Workers KV と Access はコアプロキシに依存しており、障害の影響が拡大
- 13:04に Workers KV がプロキシをバイパスするようパッチを適用し、エラー率が低下
- Dashboard は Turnstile と Workers KV に依存していたためログイン不可
- 11:30〜13:10、14:40〜15:30の2回にわたり可用性が低下
- バックログと再試行リクエストにより遅延が増加し、15:30ごろ復旧
- 14:30以降は大半のサービスが正常化し、17:06に完全復旧
再発防止策
- Cloudflare が生成する設定ファイルの入力検証を強化
- グローバル機能停止スイッチ(kill switch)の拡充
- エラー報告によるシステム資源枯渇の防止
- コアプロキシモジュール全体のエラー条件を見直し
タイムライン要約(UTC)
| 時刻 |
状態 |
説明 |
| 11:05 |
正常 |
データベースアクセス制御変更をデプロイ |
| 11:28 |
影響開始 |
顧客トラフィックで最初のエラーが発生 |
| 11:32–13:05 |
調査進行 |
Workers KV エラーの原因を分析し、緩和を試行 |
| 13:05 |
影響縮小 |
Workers KV および Access のバイパスを適用 |
| 13:37 |
復旧作業集中 |
Bot Management 設定ファイルのロールバック準備 |
| 14:24 |
問題ファイル配布停止 |
正常ファイルのテスト完了 |
| 14:30 |
主な影響解消 |
正常ファイルをグローバル配布し、サービス復旧開始 |
| 17:06 |
完全復旧 |
すべてのサービスの正常化が完了 |
結論
- 今回の障害は、Bot Management 設定ファイル生成ロジックとデータベース権限変更の相互作用によって発生
- Cloudflare はこれを2019年以降で最も深刻なネットワーク停止と評価
- 今後はシステム回復力を高めるための構造的改善と、自動化された防御体制の強化を進める
8件のコメント
設定ファイル関連の障害はどこでも起きますね。
Cloudflare が使えなくなると、ありとあらゆるサービスが止まってしまって、まさに地獄でした……
原因分析の文書、かなり早く公開されましたね…!
そういえば、この記事の執筆者はCEOだったんですね
Hacker Newsの意見
これは数百万ドル級の .unwrap() 事故譚 だ
インターネットの中核インフラの経路で
.unwrap()を呼ぶというのは、「絶対に失敗しない、失敗したらその場でスレッドを殺す」という宣言に等しいRust コンパイラは失敗可能性を明示的に表現するよう強制するが、彼らは優雅に処理せずパニックを選んだ
典型的な「parse, don’t validate」アンチパターンの例だと思う
.unwrap()に 盲点 を持っているように見える。サンプルコードでよく見かけるからかもしれない実運用コードでは
.unwrap()や.expect()はパニック同様にレビューすべきだプロダクションコードで
.unwrap()を使うなら必ず “INFALLIBILITY” コメントを付けるべきで、clippy::unwrap_usedでそれを強制できる単に
.unwrap()のせいではなく、クエリがデータベースを区別していなかったためペイロードが大きくなり、ClickHouse がより多くの DB を露出したためだ「unwrap のせい」と断定するより、グローバル・キルスイッチ やシステム資源を圧迫しないようにする設計改善のほうが重要だと思う
FL2 レイヤーで各コンポーネントのパニックを捕捉すべきだが、fail-open が常により良いとは限らない
パニックを捕捉して処理するかどうかを FL2 レベルで明示的に決めるロジックを追加すべきだ
シャーディングされたシステム なら、なぜ段階的ロールアウトと監視がなかったのかも気になる
!アンラップと明示的な?アンラップがある私は暗黙的アンラップをほとんど使わない。保証された値でも常に明示的に扱う
たとえば
@IBOutlet weak var someView!の代わりに@IBOutlet weak var someView?と定義する一種の belt & suspenders アプローチだ
障害から 24 時間も経たずに post mortem を公開したのは本当にすごい
たいていの大企業なら複数の stakeholder によるレビューのせいでコード公開はほぼ不可能だ
Cloudflare の障害説明を読みながら、「なぜ復旧にあんなに時間がかかったのだろう」と思った
障害原因は理解したが、ネットワークの大半が落ちたなら 直近の設定変更を戻すのが最優先 ではないかと思えた
もちろん事後的には明白だが、7 分で調査を開始したのは印象的だ
この事件は CrowdStrike 事故 に似ていると感じる
自動生成された設定ファイルがソフトウェアを壊し、それがネットワーク全体へ伝播した
迅速なデプロイが必要なのは理解するが、今回は 段階的ロールアウトとロールバック戦略 の欠如を露呈した
Cloudflare が発表した今後の改善計画を見ると、
などがある
しかし カナリアデプロイや段階的構成配布 は抜けている
グローバルスイッチは危険になり得るし、バグ一つでシステム全体を止める可能性もある
なぜ ClickHouse を feature flag ストア として使ったのかも疑問だ。ClickHouse deduplication ドキュメント にもリスク要因がある
サービス間の 依存関係マッピング があれば原因追跡ははるかに容易になるだろう
コードデプロイは慎重なのに設定デプロイはそうではない。設定もコードだという認識が必要だ
ステータスページが落ちて攻撃と誤認したという部分は興味深い
Cloudflare インフラとは完全に分離されているというのに、なぜ一緒に死んだのか説明がない
私は Turnstile を fail-open 戦略 で統合していたので、今回の障害で効果があった
JS が読み込まれなければダミートークンで送信を許可し、バックエンドで検証に失敗しても fail-open で処理する
一部のユーザーは依然としてブロックされたが、全体への影響は減らせた
他の ボット緩和手段 があるからこそ可能なアプローチだ
だがこれは 標的型攻撃ではない場合にのみ 通用しそうだ
なぜ Cloudflare のコードで
.unwrap()が許されていたのか疑問だ少なくとも
expect("これは絶対に起きない")くらいは使うべきだったエラーを値として扱う哲学 は、まさにこうした問題を防ぐためのもので、診断もはるかに容易になったはずだ
ネットワーク呼び出しを含むコードでは失敗可能性が多すぎる
開発中は
.unwrap()を使うが、プロダクションではしばしば expect() を残すこともある。これ以上進める方法がない場合があるからだ本当の教訓は、あまりに多くの機能が 少数のプレイヤー に依存しているという点だ
勝者総取りの構造が強まり、システムの レジリエンス は低下している
もちろん彼らが実力で得た地位ではあるが、インターネットが常に「正常動作」することを期待するのは行き過ぎだと思う
「Rust なら全部安全」という話は誇張だ
どんな言語でも 使い方を誤れば銃口を自分の足に向ける のと同じだ
Cloudflareほどの会社でも
.unwrap()を使うんですね…。 そのコードがどうやって本番環境に入ったんだろうunwrapが問題ではないように思います根本的な問題は誤ったクエリです。
でも、
unwrapで問題の検証を省略したことも問題だったと思います。内部的に問題が起きたとしても、エラー処理をしていればトラフィックが落ちることはなかったはずです。