← ブログに戻る

バリデータがバグっていた — 「安全です」と報告するシステム自身が壊れているとき

デバッグsre障害対応ポストモーテム監視

先に結論を言います。最も危険なバグは、コードの中ではなく「OK」と報告する側にいます。 監視ダッシュボード、ヘルスチェック、デプロイ前のバリデータ。これら「安全です」と告げてくる計器そのものが壊れているとき、デバッグは一気に泥沼化します。

恥ずかしい話からします。私は昔、本番の数字が変だという報告を受けて、まずダッシュボードを開きました。グリーン。全部グリーン。だから「監視が正常なんだから問題ない、報告側の勘違いだろう」と判断して、30分くらい何もしませんでした。実際には集計バッチが止まっていて、ダッシュボードは古い値を表示し続けていただけでした。グリーンだったのは、健康だったからではなく、心電図のコードが抜けていたからです。

この「計器を信じすぎる」という失敗は、規模が大きくなると桁違いの被害になります。

850万台を落としたのは、バリデータのバグだった

2024年7月19日、CrowdStrikeのFalcon Sensorアップデートが世界中のWindowsをブルースクリーンに変えました。その数、約850万台。航空会社のチェックインが止まり、病院のカルテが開かなくなり、決済端末が沈黙しました。医療業界だけで被害見込みは約19.4億ドルとされています。

原因はマルウェアでも外部攻撃でもありません。デプロイ前の検証システム、Content Validatorのバグでした。

技術的にはこうです。Channel File 291の更新で使われたIPCテンプレートは 21個の入力フィールド を定義していました。ところが、それを実際に解釈するセンサー側のコードは 20個 しか渡していませんでした。21対20。たった1個のズレです。

普通ならバリデータがこの不一致を弾くはずでした。チームもそう信じていました。3月から4月にかけて、同種の更新が何度も成功していたからです。ところがバリデータ自身にバグがあり、この21番目のフィールドのズレを検知できませんでした。テストでは21番目に常にワイルドカード(何にでもマッチする条件)が使われていたため、不一致が一度も表面化しなかったのです。結果、カーネルレベルの境界外メモリ読み取りが起き、世界中のマシンが同時に倒れました。

「バリデータが通したんだから安全だ」。この前提が、850万台分の崩壊を招きました。怖いのは、誰も嘘をついていないことです。バリデータは正直に「安全です」と報告していた。報告する機能そのものが壊れていただけです。

21フィールドを検証したバリデータと20フィールドしか渡さなかったセンサーの不一致を示す図

グレー障害 — 「応答できる」と「正しく動く」は別物

この種の故障には名前があります。グレー障害(gray failure) です。完全にダウンすれば監視が即座に気づきます。完全に正常なら問題ありません。やっかいなのはその中間、つまり「生きてはいるが正しく動いていない」状態です。

ある決済プラットフォームで、データベースノードがこの状態に陥った事例があります。ノードはヘルスチェックに応答し続けていました。だから監視は「正常」と報告し、フェイルオーバーも発動しませんでした。実際にはレプリケーションが止まっていて、データはどんどん古くなっていきました。

ヘルスチェックが見ていたのは「このノードは応答できるか」だけでした。「このノードは正しく仕事をしているか」は見ていなかった。この2つは、似ているようでまったく別の質問です。pingが返ってくることと、中の人がちゃんと働いていることは違います。会社のチャットで即レスする人が、必ずしも仕事を進めているとは限らないのと同じです。

ヘルスチェックには常に死角があります。何を検査しているのか、そして何を検査して いない のかを、書いた本人すら忘れがちなのです。

内部ツールも、同じネットワークに乗っていた

計器を疑うべき理由はもう一つあります。障害そのものが、計器を巻き込むことがあるからです。

2021年10月4日、Meta(Facebook)が約6時間にわたってインターネットから消えました。バックボーンのメンテナンス作業でコマンドを誤り、全バックボーン接続が切れ、DNSサーバーがBGP経路を撤回しました。Facebook、Instagram、WhatsAppが世界中で同時に沈黙しました。

エンジニアが最初に手を伸ばしたのは、いつもの内部ツールでした。ところがその内部ツールが、落ちたのと同じネットワークに依存していました。リモートでデバッグする手段がすべて使えなくなり、最終的に人が物理的にデータセンターへ向かうことになりました。

「内部ツールはいつでも使える」。平時には正しいこの前提が、有事には真っ先に崩れます。火事のときに限って消火器の前に火が回っている、というやつです。監視も、ログ基盤も、踏み台サーバーも、それ自体が障害の被害者になりうる。そう考えておくだけで、初動の選択肢が変わります。

過去の成功体験という、いちばん手強い計器

人間の頭の中にも、壊れた計器があります。過去の成功体験です。

2021年2月28日、みずほ銀行のe口座一括切替処理が、MINORIコアバンキングの定期預金データ領域を溢れさせました。ATM 4,318台が停止し、5,244枚のキャッシュカードと通帳が機械に呑み込まれました。引き出せなくなった人が、休日のATMの前で立ち尽くす光景です。

対応チームが取った行動は、過去の障害で有効だったエラー閾値の緩和でした。前回はこれで収まった。だから今回も、と。ところが状況は違っていました。閾値の緩和は、残っていた最後の安全バリアを外し、障害をさらに広げてしまいました。

後の調査委員会は、根本原因を「技術」ではなく「組織文化」に求めました。「前回これで直った」という記憶が、検証されないまま今回に適用された。過去の成功は、もっとも疑いにくい計器なのです。よく効いた薬を、別の病気にそのまま飲ませてしまった、と言い換えてもいい。

計器を疑うための、実務の一手

では具体的に何をするか。私が現場で使っているのは、シンプルなルールです。

「本当に?」を3回繰り返す。 ログが正しい? 本当に? ならログ基盤自体のステータスを見る。影響はこの2社だけ? 本当に? ならフィルタを外して全件を見る。前回と同じ対処で直る? 本当に? なら前回との差分を明示的に並べる。

「What」を最後に回す。 デバッグはつい「何が壊れた?(What)」から始まります。でもその前に確認すべきことがあります。どこから観測している?(Where)その観測点は信頼できる? いつから?(When)本当にその時刻から? どうやって検知した?(How)その検知手段自体は生きている? これらが固まってから、初めてWhatを考えます。

そして最後に、自分用のチェックリストを一つ。

  • ログは全件出ているか(欠損はないか)
  • メトリクスの計測自体にバグはないか
  • ヘルスチェックは「正しく動く」を見ているか、「応答できる」だけを見ているか
  • 監視システム自体が、今回の障害の影響を受けていないか
  • 「N件だけ」のNは、本当にNか(フィルタは正しいか)
  • 前回と同じ対処が効くという根拠は、今回もあるか

計器を疑うのは、後ろ向きな作業ではありません。観測が信頼できると確認できて初めて、その先のデバッグ全部の精度が上がります。土台が砂のままどれだけ立派な仮説を積んでも、それは砂上の楼閣です。グリーンのダッシュボードを見て安心する前に、一度だけ「このグリーンは、本当にグリーンか?」と問う。私が30分を無駄にして学んだのは、結局それだけのことでした。