23 ポイント 投稿者 GN⁺ 2025-11-19 | 8件のコメント | WhatsAppで共有
  • 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件のコメント

 
t7vonn 2025-11-19

設定ファイル関連の障害はどこでも起きますね。

 
princox 2025-11-19

Cloudflare が使えなくなると、ありとあらゆるサービスが止まってしまって、まさに地獄でした……

 
epdlemflaj 2025-11-19

原因分析の文書、かなり早く公開されましたね…!

 
epdlemflaj 2025-11-19

そういえば、この記事の執筆者はCEOだったんですね

 
GN⁺ 2025-11-19
Hacker Newsの意見
  • これは数百万ドル級の .unwrap() 事故譚
    インターネットの中核インフラの経路で .unwrap() を呼ぶというのは、「絶対に失敗しない、失敗したらその場でスレッドを殺す」という宣言に等しい
    Rust コンパイラは失敗可能性を明示的に表現するよう強制するが、彼らは優雅に処理せずパニックを選んだ
    典型的な「parse, don’t validate」アンチパターンの例だと思う

    • 多くの人が .unwrap()盲点 を持っているように見える。サンプルコードでよく見かけるからかもしれない
      実運用コードでは .unwrap().expect() はパニック同様にレビューすべきだ
      プロダクションコードで .unwrap() を使うなら必ず “INFALLIBILITY” コメントを付けるべきで、clippy::unwrap_used でそれを強制できる
    • この記事の要点は、単一原因よりも 正常な構成要素の組み合わせ が問題を引き起こすということのようだ
      単に .unwrap() のせいではなく、クエリがデータベースを区別していなかったためペイロードが大きくなり、ClickHouse がより多くの DB を露出したためだ
      「unwrap のせい」と断定するより、グローバル・キルスイッチ やシステム資源を圧迫しないようにする設計改善のほうが重要だと思う
    • 実際にはこれは Rust 経路以外でも失敗していた。ボット管理システムが全トラフィックをボットとして分類したからだ
      FL2 レイヤーで各コンポーネントのパニックを捕捉すべきだが、fail-open が常により良いとは限らない
      パニックを捕捉して処理するかどうかを FL2 レベルで明示的に決めるロジックを追加すべきだ
    • もし優雅に処理していたら性能低下はあった気がする(それでも信頼性低下よりはましだと思う)
      シャーディングされたシステム なら、なぜ段階的ロールアウトと監視がなかったのかも気になる
    • Swift には暗黙的な ! アンラップと明示的な ? アンラップがある
      私は暗黙的アンラップをほとんど使わない。保証された値でも常に明示的に扱う
      たとえば @IBOutlet weak var someView! の代わりに @IBOutlet weak var someView? と定義する
      一種の belt & suspenders アプローチだ
  • 障害から 24 時間も経たずに post mortem を公開したのは本当にすごい

    • これほど速く透明性高く公開できる社内ポリシーが気になる
      たいていの大企業なら複数の stakeholder によるレビューのせいでコード公開はほぼ不可能だ
    • しかも文章自体もよく書けている。AWS のポストモーテムと比べると、ほとんど文学の域だ
  • Cloudflare の障害説明を読みながら、「なぜ復旧にあんなに時間がかかったのだろう」と思った
    障害原因は理解したが、ネットワークの大半が落ちたなら 直近の設定変更を戻すのが最優先 ではないかと思えた
    もちろん事後的には明白だが、7 分で調査を開始したのは印象的だ

    • 最初は攻撃と誤認していた。その後問題を把握したが、破損したファイルをキュー内で置き換える方法がなく、世界中の膨大なマシンを再起動する必要があった
  • この事件は CrowdStrike 事故 に似ていると感じる
    自動生成された設定ファイルがソフトウェアを壊し、それがネットワーク全体へ伝播した
    迅速なデプロイが必要なのは理解するが、今回は 段階的ロールアウトとロールバック戦略 の欠如を露呈した

    • これは CI/CD デプロイというより 分散ボット検知システムの制御チャネル と見るべきだ
    • シミュレーターなしでいきなり本番へプッシュしたのは驚きだ
    • それでも今回をきっかけに改善が進むと信じている
  • Cloudflare が発表した今後の改善計画を見ると、

    • Cloudflare 生成設定ファイルの検証強化
    • グローバル・キルスイッチ の追加
    • コアダンプやエラーレポートによるリソース枯渇の防止
    • プロキシモジュールのエラーモードの見直し
      などがある
      しかし カナリアデプロイや段階的構成配布 は抜けている
      グローバルスイッチは危険になり得るし、バグ一つでシステム全体を止める可能性もある
    • ボット管理設定は速く伝播する必要があるが、1 インスタンスで先にテストしていればパニックを事前に捕捉できたはずだ
      なぜ ClickHouse を feature flag ストア として使ったのかも疑問だ。ClickHouse deduplication ドキュメント にもリスク要因がある
    • 設定サービスには段階的ロールアウトがあったが、消費するサービス群があまりにも頻繁に自動更新され、小さな割合のエラーでも全体に影響した
    • グローバル設定は迅速な対応に有用だが、高速ロールバック体制 が必須だ
      サービス間の 依存関係マッピング があれば原因追跡ははるかに容易になるだろう
    • 結局のところ、大規模障害の大半は config push が原因だ
      コードデプロイは慎重なのに設定デプロイはそうではない。設定もコードだという認識が必要だ
  • ステータスページが落ちて攻撃と誤認したという部分は興味深い
    Cloudflare インフラとは完全に分離されているというのに、なぜ一緒に死んだのか説明がない

    • おそらく トラフィック急増 によるインフラ拡張失敗の可能性が高い
    • 実際には Cloudflare 依存はないと思っていたが、インターネットのかなりの部分が CloudFront に依存しているため、完全には独立していなかったのかもしれない
    • 原因を知るには statuspage.io のポストモーテム が必要だ。Atlassian が運営するサービスだ
    • 単純に Cloudflare の規模が大きすぎてトラフィックが集中した可能性もある
  • 私は Turnstile を fail-open 戦略 で統合していたので、今回の障害で効果があった
    JS が読み込まれなければダミートークンで送信を許可し、バックエンドで検証に失敗しても fail-open で処理する
    一部のユーザーは依然としてブロックされたが、全体への影響は減らせた
    他の ボット緩和手段 があるからこそ可能なアプローチだ

    • それなら攻撃者がスクリプトを遮断すれば CAPTCHA を回避できるのでは、という疑問がある
      だがこれは 標的型攻撃ではない場合にのみ 通用しそうだ
  • なぜ Cloudflare のコードで .unwrap() が許されていたのか疑問だ
    少なくとも expect("これは絶対に起きない") くらいは使うべきだった
    エラーを値として扱う哲学 は、まさにこうした問題を防ぐためのもので、診断もはるかに容易になったはずだ

    • 私は Cloudflare の社員ではないが Rust はかなり使う
      ネットワーク呼び出しを含むコードでは失敗可能性が多すぎる
      開発中は .unwrap() を使うが、プロダクションではしばしば expect() を残すこともある。これ以上進める方法がない場合があるからだ
  • 本当の教訓は、あまりに多くの機能が 少数のプレイヤー に依存しているという点だ
    勝者総取りの構造が強まり、システムの レジリエンス は低下している
    もちろん彼らが実力で得た地位ではあるが、インターネットが常に「正常動作」することを期待するのは行き過ぎだと思う

  • 「Rust なら全部安全」という話は誇張だ
    どんな言語でも 使い方を誤れば銃口を自分の足に向ける のと同じだ

 
barca105 2025-11-19

Cloudflareほどの会社でも .unwrap() を使うんですね…。 そのコードがどうやって本番環境に入ったんだろう

 
skageektp 2025-11-19

unwrap が問題ではないように思います

 
barca105 2025-11-19

根本的な問題は誤ったクエリです。
でも、unwrap で問題の検証を省略したことも問題だったと思います。
内部的に問題が起きたとしても、エラー処理をしていればトラフィックが落ちることはなかったはずです。