- 2025年6月12日、Google Cloud と Google Workspace のサービスで、外部 API リクエスト中の 503 エラー が世界的に増加
- エラーの原因は、Service Control システムのコード変更と、空フィールドを含む誤ったポリシーデータの反映
- コアバイナリの エラー処理不足 と機能フラグ未適用などが、問題の拡大を招いた
- 復旧には2~3時間を要し、us-central-1 リージョンではインフラ過負荷によりさらに長い復旧時間が発生
- Google は アーキテクチャ分離、エラー処理改善、データ検証強化 などの再発防止策を発表
障害の全体概要
Google Cloud および Google Workspace サービス障害の要約
- 2025年6月12日午前10時49分(PDT)から、Google Cloud、Google Workspace、Google Security Operations を含む複数サービスで、外部 API リクエスト に対する 503 エラー が急増する事象が発生
- 顧客サービスと信頼に深刻な影響を与えたことについて、Google は深く謝罪の意を表明
- Google の API 管理および制御プレーンは、各リクエストの ポリシーおよびクォータチェック を担当しており、中核チェックシステムは
Service Control というバイナリとして動作
障害原因の分析
変更されたシステム構成 – Service Control
- 2025年5月29日、Service Control に クォータポリシー検査を強化する新機能 が追加
- リージョンごとに段階的なロールアウトを進めていたが、問題のコードは ポリシーが実際に反映されたときのみ動作 し、それまではトリガーされず、事前テストが不十分だった
- この新機能パスには適切な エラー処理と機能フラグ がなく、null ポインタ状況でバイナリが連鎖的にクラッシュ
障害発生の経緯
- 2025年6月12日午前10時45分(PDT)、ポリシー変更が Regional Spanner テーブルに挿入
- このポリシーデータには意図しない 空フィールド(Blank Field) が含まれており、これが世界中にほぼリアルタイムで複製
- Service Control がこのポリシーを処理する過程で、null ポインタ によるクラッシュが発生し、各リージョンのインスタンスがグローバルに Crash Loop に陥った
- 2分で SRE チームが認知を開始し、10分以内に原因を特定した後、暫定的にバイナリ経路を遮断(red-button)し、40分で大半のリージョンは復旧
追加の復旧上の問題
- 一部の大規模リージョン(us-central-1)では、Service Control タスク再起動時の herd effect によりインフラ(Spanner テーブル)が過負荷
- Service Control が ランダム化指数バックオフ を適用しておらず、インフラ負荷をさらに増大させた
- 当該リージョンでは最大2時間40分まで復旧が遅延したが、トラフィック迂回などで影響を最小化し、最終的に全体としてサービス復旧が完了
顧客影響および障害範囲
- 顧客には API およびユーザーインターフェースへのアクセス障害 が発生し、ストリーミングおよび IaaS リソースには影響なし
- 遅延およびバックログの影響は、一部サービスで最大1時間以上継続
- 影響を受けた Google Cloud および Google Workspace 製品の一覧が広範囲に示された
- 例: IAM、Cloud Build、Cloud Storage、BigQuery、AppSheet、Gmail、Google Drive など数十のサービス
今後の改善策
- サービスアーキテクチャをモジュール化 し、各機能を分離するとともに、障害発生時には開放型(fail open)の処理を導入
- グローバルデータ複製の段階的伝播 と実効的な検証プロセスを強化
- すべての主要バイナリ変更時に 機能フラグ化とデフォルト無効化 を適用する方針へ改定
- 静的解析とテスト改善 により、エラー検知と障害時に fail open できる設計を検討
- ランダム化指数バックオフ 方針と、監視・コミュニケーションの信頼性を強化予定
- 障害時でも顧客に迅速な 監視および情報提供 が行えるよう、インフラ冗長化と自動化コミュニケーションを補強
障害告知とコミュニケーション
- 事故後1時間以内に Cloud Service Health へ告知したが、監視インフラ自体にも障害が発生
- 一部顧客では、Google Cloud ベースの監視システム自体が正常動作せず、障害シグナルや影響の把握が困難だった
- Google は今後、監視および顧客向けコミュニケーション基盤の強化 を約束
主な障害タイムライン(ミニレポート要約)
- 障害開始: 2025年6月12日 10:49(PDT)
- 大半のリージョン復旧: 2025年6月12日 12:48(PDT)
- 障害終了: 2025年6月12日 13:49(PDT)
- 総所要時間: 約3時間
- 影響地域: 全世界
事後対策の要約
- API 管理プラットフォーム でデータエラーや破損が発生した際の障害防止措置を整備予定
- グローバルメタデータ伝播 前の検証・テスト・監視を強化
- 無効なデータに対する システムエラー処理および総合テスト を拡充
影響サービス一覧(抜粋)
Google Cloud の主なサービス
- Identity and Access Management, Cloud Build, Google Cloud Storage, Cloud Monitoring, BigQuery, Vertex Gemini API, Cloud Firestore, Looker, Cloud Run, Compute Engine など
Google Workspace の主なサービス
- AppSheet, Gmail, Google Drive, Google Meet, Docs, Chat, Calendar など
結論
- 今回の障害は、ポリシー/クォータ管理システムの構造、データ完全性検証の不足、エラー処理体制の欠如 が複合的に作用した問題
- Google は アーキテクチャレベルでの改善 と障害対応力の強化を約束
2件のコメント
GN+ではない版の記事リンクです。
Hacker Newsの意見
内部者の立場なので一時アカウントを使っているが、今回の事故の根本原因は、リーダーシップがスピードを出すために原則を無視したことにある。この慣行が何年も続き、ついに限界に達した。今回起きた「query of death」は、特定のクエリによってサーバーがクラッシュする古いC++サーバーでは避けがたく発生する典型的な失敗パターンだ。Service ControlはC++で書かれており、さまざまなエンジニアリングガイドラインを活用してこうした失敗を最小化しようとしてきた。10年間大きな事故なく運用されてきたが、最近のリーダーシップの圧力の下で急いで作られたグローバルクォータポリシーが問題だった。こうした新機能は別サービスとして開発するか、少なくとも既存のガイドラインを守るべきだった。公式報告書で言及された対策より、チームが本来守ってきた標準の方がはるかに高い。チームはできる限り既存の基準を維持しようと努力している
事故報告書は興味深いと思う。SREチームが2分で素早く対応し、「red button」ロールアウトが始まった。問題は、us-central-1のような大規模リージョンでService Controlタスクが再起動すると、インフラ(Spannerテーブル)に過負荷がかかる「herd effect」が現れたことだ。Service Controlにランダム化された指数バックオフが実装されていなかったため、完全復旧は2時間40分まで遅れた。こういう状況では通常のクォータがすぐに超過し、新たな障害につながる。このような場合、インフラが耐えられるならクォータを一時的に停止するか、復旧作業をゆっくり制限するのも良いと思う
これは本当にアマチュアのようなミスだと思う。NPE、エラーハンドリングなし、指数バックオフなし、テストカバレッジなし、ステージング環境でのテストなし、段階的ロールアウトなし、どれも深刻な失敗だ。SRE本にすでに全部書いてある内容だ Google SRE Book 目次, Building Secure and Reliable Systems TOC。基準が低くなりすぎたのか、それとも本がただのマーケティングなのか気になる
私の考えでは、人間であれ自動化であれ防御策に完全さはなく、結局はトレードオフの連続だ。どれだけ多くのユニットテストや統合テスト、静的解析、順次デプロイをしても、規模が大きくなれば予想外の抜け穴は避けられない。これは本にある「もう1つ9を追加するには、はるかに大きな努力が必要になる」のと同じ理由だ。最悪の場合、スタック全体を複製して数か月分のトラフィックをすべて再生しなければならないかもしれないが、そんなレベルのコスト対効果は誰にも負担できない。OpenZFS作業でも、コード自体は正常に見えたのに10年前に書かれたデータのエッジケースで問題が表面化した経験がある。システムが十分に複雑になると、すべてのバリエーションをテストすることは不可能になるので、現実的には費用対効果を基準に決めるしかない。参考までにGoogleのSREだが、この事件とは無関係のチームであり個人意見だ
ほぼすべてのGoogleのグローバル障害はこれと似た形で展開する。つまり、急速にグローバル展開されたカスタムシステムが誤った設定を取り込む。一般的なバイナリロールアウトや設定プッシュでは段階的ロールアウトが適用されるのが普通だ。Google Cloudでも以前はさまざまなシステムがグローバルに束ねられていたが、今ではかなりリージョン化されて信頼性も上がっている。以前はグローバル障害がしばしばあったが公開されなかったため、ほとんどのユーザーは自分のISPの問題だと認識していた。今が特別に悪化しているとは思わない。ちなみにSRE経験もある
外部の立場から考えると、大規模な構造調整やCEOの「怠惰」発言など以降、皆が品質よりスピードと可視的成果に偏るようになった。こうした文化を問題視すると、むしろ排斥されるような環境変化が起きている
もっと詳しい情報が公開されてほしい。私としては、ここで言われているようにテストされていなかったのではなく、ポリシーの空フィールド(問題となる入力)に対するテストがなかったのだと見ている。ステージング環境でのテストがなかったという説明でもないし、フラグがあれば捕捉できたはずという話だ。個人意見だ
「最も危険な道具でも慣れてしまうと慎重さを失い、指針が不必要に厳しすぎると思うようになる」という1864年の火薬庫報告書を思い出す
私はCloud内の別チーム所属だ。一般的にすべてのコードにはユニットテストと統合テストがある。バイナリや設定変更は作業単位・リージョン単位で数日にわたり段階的に行われ、カナリア分析も伴う。ロールバックでさえ急ぎすぎると状況を悪化させる可能性があるため、ゆっくり進める。たとえばグローバルデータベースを一気に過負荷にするより、40分の停止の方が4時間の障害よりましだと判断する。今回の事故に直接関与してはいないが、PMを見る限り、コードはテストされていたもののこのエッジケースは漏れていた。問題は、クォータポリシー設定がバイナリや設定ファイルではなくデータベース更新として適用され、世界中のすべてのデータベースに数秒で変更が広がったことだ。nullポインタの問題は、他の言語でもassert()で起きていた可能性がある。こうした中核サービスを別の言語に書き直すリスクよりも、すべてのポリシーチェックにフラグガードを適用し、クォータポリシーチェックはfail openにし、DB変更をリージョン別にゆっくり拡散させる方が合理的だ。個人意見だ
assertはポリシーとして禁止する方がずっと簡単な構造だ
コードはテストされていたが、このエッジケースが漏れていたのだから、結局テストしていないのと同じだという反論だ
DB変更がバイナリや設定変更でないからといって問題が変わるわけではない。変更そのものが同時に全世界へ広がるなら、どんな種類でも災厄の種だ。Crowdstrike事案とまったく同じ流れだ
「言語を変えて書き直すのはリスクが高すぎる」という意見なら、つまりサービス要件がきちんと把握されていないのか、それとも慎重な移行が必要なほど重要なサービスではないのか気になる
適切なエラーハンドリングなしにnullポインタでバイナリがクラッシュしたという話だ。この段階になると「trillion dollar mistake」という冗談が出てもおかしくない
今回の事故で年間分のSLAをいくつ吹き飛ばしたのだろうか
こういう問題を防いでくれる言語があれば、と思っての /s(皮肉)だ
Service Control(Chemist)はかなり古いサービスで、複数のGCP APIにおいて認証、権限、監視、クォータなど中核的な役割を担っている。リクエストフロー上、多くのGCP APIがChemistを経由する(なのでfail open緩和策は実効性が低いと思う)。ChemistもプロキシもC++で書かれており、長年にわたり多くのレガシーコードが積み上がっている。各チームは静的解析、テスト、段階的デプロイ、フィーチャーフラグ、red button、強力な監視およびアラートシステムを備えている。特にSREチームは優秀だ。ChemistではIAM、クォータなどさまざまなポリシーを検証するため、多くのチームがコードベースに貢献している。変更のたびにChemistの承認プロセスを通りたくないため、近道で開発された部分が増えた。最近は組織改編やオフショア化が多く、L8/L9級主導の派手な新規プロジェクトに偏り、品質・保守・信頼性は後回しになっている(こうした文化変化のせいでCloudを離れた)。Googleの一般的なサーバー/サービスのベストプラクティスが、ここでは守られないことが多い。今回の問題はコードとコードレビューの甘さに近く、欠陥のあるコードを承認し、Spannerで設定変更を即時反映させたことで問題が拡大した
サービスポリシーデータに意図しない空フィールドが含まれており、Service Controlが各リージョンでクォータチェック時に空フィールド(null)を読んで例外が発生した。Hoareの「十億ドルの過ち」が複数のGoogleシステムで繰り返された例だ。そもそもこうした「空フィールド」(null)が入り得るよう許したのが問題で、スキーマでnull不許可(
NOT NULL)を明示すべきだった。不運なことにSpannerはデフォルトでnullableなので別途指定が必要だ。アプリコードレベルでも、型システムやスキーマ言語を通じて無効な状態が不可能になるよう設計する機会があった。データストアからアプリオブジェクトへ逆シリアライズする際に、スキーマの強制検証を追加する方法もある。本文の問題が新しいコードパスで起きた以上、データ層で弾かれなかったのではないかと思う。Service Controlプログラム自体がnullポインタ参照を許す言語で書かれていることも問題だ。もし私が管理担当者なら、ポリシーをアプリコード上で「タグ付きenum型」などnullを表現できない構造に変える最小介入プランを考えるだろう。proto3にはこの制約がないが、こういう例 はあるマルチリージョンは回復力と可用性の手段としてよく語られるが、実際には障害時に大手クラウド事業者でさえリージョン間が強く結び付いているのは興味深い
これは特にGCPで顕著で、GCPはリージョンを他社とは違った形で扱っている。回復性の観点では、GCPは複数ゾーンを束ねた単一リージョンのように見るべきだ
それでも「私たちが知らない障害」は依然としてあり得るので、リージョン/ゾーンシャーディングの効果を過度に過小評価するのはよくない
マルチリージョン展開によって事故を防いだ事例も多いのだから、実際にそうしたケースを把握した上で結論を出すべきだ
Googleのポストモーテムの詳細さにはいつも驚かされる。社内外の両方でそう感じる。失敗を繰り返さないよう学び、プロトコルとエラーハンドリングを強化して、より強靭なシステムへ進化していく。Googleのような規模の大きい場所では常に何かがうまくいかないが、重要なのは顧客/ユーザーや他のシステムに影響が及ばないよう封じ込めることだ。内部にいてもチームによって見えない問題は多様だ。これは人間が作ったシステムの中でも最も複雑な部類に入ると思う。AGIでもない限り、人間がこれ以上うまくやれる領域ではない
しかし今回の事故ではジュニアレベルのミスが連続した。nullデータを処理できなかった点、テスト不足、新機能に対するテストカバレッジ不足、本番全面展開前に小規模プロダクションで検証しなかった点、どれも問題だ。10年前のGoogleなら、こういうミスは皆に笑われていたと確信している
私の理解では今回の障害原因は、1) グローバル機能が一度に全体展開された 2) nullポインタ逆参照が発生した 3) 適切なリトライポリシーがなく "thundering herd" 問題を引き起こした、の3点だ。いずれも業界の人なら見慣れた失敗で、珍しい複雑な分散システムロジックではなく、典型的な「初心者ミス」が複合的に炸裂した形だ
「二度と同じ失敗を繰り返さない」と言うが、実際にはフィーチャーフラグなしで変更をロールアウトし、クライアント側には指数バックオフも、サーバー側にはロードシェディングも実装されていなかった。これらはどれも何年も前からgoogle SRE bookに書かれている内容だ
このエラーは見逃されたnullポインタ問題だった。Googleほどの規模と品質を持つ会社が、こういう形でスタックの大部分をダウンさせるのは、深刻な問題の再発防止策が不足しているというシグナルにも読める
これは何度も繰り返されてきた同じミスだ。「新機能を慎重にデプロイするが、新しいデータが入って初めて表面化するバグ」が、ほとんどのグローバル障害を要約する文句だ。完璧なシステムは存在しない。FAANG障害論争でだけ完全無欠なのは「HNの肘掛け椅子専門家」くらいだ
たいてい、人は他人のダウンタイムを見ると「ジュニアレベルのミス」と簡単に批判するが、いざ自分の仕事になると、避けられなかった、予測不可能だったという言い訳が残る。人間のミスは避けられず、期待値そのものが高すぎる。オフラインの店が突然閉まっても「すみません」の一言で終わる。数時間の障害で過剰なストレスを受けるのはIT業界くらいなので、皆もう少し余裕を持てばいいと思う