AWS 2025年 DynamoDB の DNS の競合による us-east-1 の障害

攻撃ではない。DynamoDB の DNS を自動で更新する仕組みに、眠っていた競合があった。遅れた1つが古い計画を新しい計画の上に書き、別の1つの掃除がその古い計画を消し、地域の入口の名前から IP が全部消えた。自動化は直せない状態に陥り、人が直した。DynamoDB は約3時間で戻ったが、それに頼る EC2 の仕組みが戻る途中で詰まり、障害は14時間余り続いた。止める所は、書く時に版を比べること、使っている計画を消させないこと、空の記録を拒むこと、戻る時に仕事を絞ることにある。

米国バージニア北部の us-east-1 の地域。米国太平洋夏時間の2025年10月19日23時48分に始まり、20日14時20分に終わった[1]。一部の Redshift の群れの回復は21日4時05分までかかった[1]。AWS は事後の要約で、DynamoDB の DNS の計画と適用の自動化を世界中で止め、再び動かす前に競合を直し、誤った計画を当てない守りを足すとした[1]。再開と修正の完了は、2026年11月時点で公表されていない。2026年11月時点の公開資料で書いています。

要点

  • DNS Planner が計画を作り、3つのアベイラビリティゾーンで独立に動く DNS Enactor が Route 53 に当てる。Enactor は当て始める前に一度だけ、自分の計画が前に当てた計画より新しいかを確かめていた[1]。
  • 遅れた Enactor が、確かめの後に古くなった計画を地域の入口に書いた。新しい計画を当て終えた別の Enactor の掃除が、ずっと古いその計画を消し、入口の IP が全部消えた[1]。
  • 使っていた計画が消えたため、どの Enactor も次の計画を当てられない状態になり、人の手が要った[1]。
  • DynamoDB に頼る EC2 の物理の機械の管理が、戻る時に仕事の山で詰まり、新しいインスタンスの起動が10時36分まで失敗した。網の設定の遅れから NLB の健全性の確かめが揺れ、接続の誤りが14時09分まで続いた[1]。
  • AWS は、自動化の停止のほか、NLB の容量を外す速さの制御、EC2 の回復の手順の試験、待ち行列の長さに応じた絞りを挙げた[1]。

何が起きたか

19日23時48分に DynamoDB の入口が空になり、20日2時25分に DNS が戻り、EC2 の管理の詰まりと網の設定の遅れを経て、14時20分に終わるまでの4つの段 1 入口が空に 19日23時48分 DynamoDB に 名前で届かない 2 DNS が戻る 20日0時38分に特定 2時25分に復元 2時40分に解消 3 EC2 が詰まる 機械の貸し出しの 結び直しが崩れる 網の設定も遅れる 4 終わる EC2 は13時50分 NLB は14時09分 全体は14時20分 時刻は米国太平洋夏時間。始まりと気付きは同じ夜 原因の特定まで50分、DNS の復元まで約2時間40分、全体で約14時間30分
図1 DNS の障害と、それに続く2つの長い障害
日時 米国太平洋夏時間出来事
2025年10月19日 23時48分地域の入口 dynamodb.us-east-1.amazonaws.com の DNS の記録が空になる。公開の入口から DynamoDB につなぐ全部の仕組みで、名前の解決が失敗する。社内の仕組みも同じ[1]。同時に、EC2 の物理の機械を管理する仕組みの定期の確かめが失敗し始める[1]
10月20日 0時38分DynamoDB の DNS の状態が原因と突き止める[1]
1時15分一時の緩和で、一部の社内の仕組みが DynamoDB につながり、復旧に要る社内の道具が直る[1]
2時25分DNS の情報を全部戻す。2時32分に、全部のグローバルテーブルの写しが追いつく[1]
2時25分から40分手元に残った DNS の記録が期限を迎え、利用者が入口を引けるようになる。DynamoDB の主な障害が終わる[1]
2時25分からEC2 の機械の管理が貸し出しの結び直しを始めるが、数が多く、結び終える前に時間切れになり、やり直しの仕事が積もって進めなくなる[1]
4時14分入ってくる仕事を絞り、管理の機械を選んで再起動する[1]
5時28分全部の物理の機械と結び直し、新しい起動が通り始める。網の設定を新しいインスタンスへ配る仕事の山が残る[1]
5時30分一部の NLB で接続の誤りが増え始める[1]
6時21分網の設定の配布が遅くなり始める[1]
6時52分NLB の健全性の確かめの失敗の増加を監視が検知する[1]
9時36分NLB の健全性の確かめによる自動の切り替えを止める。接続の誤りが解ける[1]
10時36分網の設定の配布の時間がふだんに戻り、新しいインスタンスの起動がふだんどおり動く[1]
11時23分絞りを緩め始める[1]
13時50分EC2 の全部の API と起動がふだんどおりになる[1]
14時09分NLB の自動の切り替えを戻す[1]
14時20分障害が終わる[1]
10月21日 4時05分入れ替えの仕事で止まっていた Redshift の群れを戻し終える[1]
  • 動いていた EC2 のインスタンスは、障害の間も影響を受けなかった[1]。止まったのは、新しい起動、状態の変更、それらに頼る仕組みだった。
  • 影響を受けた利用者の数や損害の額は、AWS の要約には無い。

起きた仕組み

遅れた Enactor 1 が始めに一度だけ版を確かめ、その間に Planner が新しい計画を作り、Enactor 2 が新しい計画を当てて掃除で古い計画を消す。Enactor 1 が古い計画を書いた直後に消され、入口が空になる Enactor 1 地域の入口の記録 Enactor 2 計画 N を取る 前より新しいと確かめる ほかの入口で ひどく遅れる Planner の新しい 計画 N+k を取る N+k を当てる N で上書き 確かめは古いまま 当て終えて掃除 ずっと古い計画を消す N を消す IP が全部消える 以後の計画も当たらない
図2 3つの Enactor のうち2つの間の競合。上から下へ時が進む
部品役割と、この件で
DNS の記録DynamoDB は、地域ごとに大きなロードバランサの群れを動かすため、数十万の DNS の記録を持つ。公開の地域の入口のほか、FIPS 用、IPv6 用、アカウントごとの入口も自動化が保つ[1]。
DNS Plannerロードバランサの健全さと容量を見て、入口ごとのロードバランサと重みの組を、定期に新しい計画として作る。IPv6 の入口と公開の地域の入口で容量を分け合うため、計画は地域で1つにしている[1]。
DNS Enactorどんな時でも復旧に使えるよう、依存を最小にして作られた。3つのアベイラビリティゾーンで独立に動き、Route 53 のトランザクションで、今の計画を新しい計画に入れ替える。当て始める前に一度だけ、自分の計画が前に当てた計画より新しいかを確かめる。入口ごとに、ほかの Enactor の更新に阻まれれば再試行する[1]。
競合1つの Enactor が、いくつかの入口の再試行でひどく遅れた。その間に Planner は新しい計画を何世代も作り、別の Enactor が新しい計画を全部の入口に素早く当てた。当て終えた Enactor の掃除が、当てた計画よりずっと古い計画を消す。ちょうどその時、遅れた Enactor が古い計画を地域の入口に書き、新しい計画を上書きした。始めの確かめは古くなっており、止めなかった[1]。
空の記録掃除が、何世代も古いその計画を消した。使っていた計画が消えたため、地域の入口の IP が全部すぐに消え、どの Enactor も以後の計画を当てられない食い違った状態が残った。人が直すまで戻らなかった[1]。
確かめた時と書いた時の差

版の確かめと書き込みが別の時にあり、間に何が起きても書き込みは通った。CWE-367 の、確かめた時と使った時の差の競合に当たる[2]。Route 53 のトランザクションは、1つの入口を一貫した計画で更新することを保つが[1]、どの計画が新しいかまでは見ていなかった。掃除は、自分が当てた計画との世代の差だけで消す計画を選び、ほかの誰かが今それを使っているかを見ていなかった[1]。どちらか1つの守りがあれば、入口は空にならなかった。

広がって長引いた道

DynamoDB の DNS の障害から、EC2 の機械の管理の貸し出しが切れ、戻る時に詰まり、網の設定の配布が遅れ、NLB の健全性の確かめが揺れて容量が外れる DynamoDB の DNS 23時48分から 2時40分まで 機械の管理 DWFM 確かめが失敗し 貸し出しが切れていく 戻る時の詰まり 結び直しが時間切れ 5時28分まで 網の設定の配布 仕事の山で遅れる 10時36分まで NLB の健全性の確かめ 失敗と成功が交互に 容量を外す 接続の誤り 5時30分から 14時09分まで Lambda、ECS、EKS、Fargate、Connect、STS、Redshift なども DynamoDB、EC2 の起動、NLB のどれかを通じて影響を受けた
図3 DNS が戻った後に始まった2つ目と3つ目の障害
仕組み何があったか
EC2 の機械の管理DropletWorkflow Manager は、EC2 を載せる物理の機械ごとに貸し出しを持ち、数分ごとに確かめる。この確かめは DynamoDB に頼っており、障害の間に貸し出しが少しずつ切れた。貸し出しの無い機械は新しい起動の候補にならず、API は容量不足を返した[1]。
戻る時の詰まりDynamoDB が戻ると結び直しを始めたが、機械の数が多く、結び終える前に時間切れになり、やり直しの仕事が積もった。AWS はこれを、進めなくなった混雑による崩壊の状態と書き、確立した復旧の手順が無かったとする[1]。
網の設定Network Manager は、新しいインスタンスに網の設定を配る。遅れていた分の山を抱え、起動できても通信できないインスタンスが出た[1]。
NLB健全性の確かめが、網の設定が届く前の新しいインスタンスを確かめて失敗し、成功と失敗を繰り返した。そのたびに DNS から外して戻し、確かめの仕組み自体も重くなり、ゾーンの自動の切り替えで容量が外れた[1]。
地域の外us-east-1 では、IAM の利用者でのコンソールへのログインが失敗した。地域の外でも、root の資格情報と signin.aws.amazon.com を使う連携のログインが失敗した。Redshift は、利用者のグループを us-east-1 の IAM の API で引く不具合のため、全地域で IAM の利用者の問い合わせが動かなかった[1]。
グローバルテーブルDynamoDB のグローバルテーブルを使う利用者は、ほかの地域の写しにつなげて読み書きできた。us-east-1 との複製は長く遅れた[1]。

どこで止められたか

書き込み、掃除、記録の中身、自動の復旧、戻り方、利用する側の6つの段に止める所を置く 書き込み 掃除 記録の中身 自動の復旧 戻り方 利用する側 1 書く時に版を比べる 条件付きの書き込みで、古い版を拒む 2 使っている計画を消させない 世代の差でなく、参照の有無で選ぶ 3 空の記録を拒む IP が0件や急減の計画は当てずに知らせる 4 食い違いから自ら戻れる 今の計画が無くても、最新を当て直せる 5 戻る時に仕事を絞る 待ち行列の長さで受け付けを絞り、外す速さも限る 6 1つの地域に隠れて頼らない ほかの地域の写しと、地域の外のログインの道
図4 段ごとの止める所
止める所この件でAWS の手当て
書く時に版を比べる版の確かめは当て始める前の一度だけで、書いた時には古くなっていた[1]自動化を再び動かす前に競合を直し、誤った計画を当てない守りを足す[1]
使っている計画を消させない掃除は世代の差だけで消し、遅れた Enactor が書いたばかりの計画を消した[1]同上。要約は個々の直し方を書いていない
空の記録を拒む地域の入口の IP が全部消えても、それを止める段が無かった[1]同上
食い違いから自ら戻れる使っていた計画が消えた状態から、どの Enactor も先へ進めず、人の手が要った[1]DynamoDB の DNS Planner と DNS Enactor の自動化を世界中で止めた[1]
戻る時に仕事を絞る機械の管理の結び直しが詰まり、復旧の手順が無かった。NLB は揺れる確かめで容量を外した[1]EC2 の回復の流れを試す試験を足す。待ち行列の長さで受け付けを絞る。健全性の確かめでゾーンを切り替える時、1つの NLB が外せる容量を限る[1]
1つの地域に隠れて頼らないグローバルテーブルの利用者は、ほかの地域の写しで読み書きを続けられた。Redshift と一部のログインは、地域の外でも us-east-1 に頼っていた[1]同じ型の事象の影響を避ける道と、復旧の時間を縮める道を、全サービスで探すとした[1]

1か2があれば、入口は空にならなかった。3は、記録を空にする操作が書き込みでも削除でも、最後に止める段になる。4は、空になった後の時間を決めた。5と6は、DNS が戻った後の11時間余りを決めた。この件で長かったのは、原因の DNS よりも、戻る時の詰まりの方である。

守り方

根本の直し方
  • 複数の書き手がいる状態は、書く時に版を比べる。確かめと書き込みを分けず、条件付きの書き込みや、比べて入れ替える操作で、今の版より古い物を拒む。
  • 掃除は、誰も参照していない物だけを消す。今当たっている計画は、世代がどれほど古く見えても消さない。
  • 結果の形に下限を置く。DNS の名前の IP が0件になる、前の版から急に減る、のような変更は当てずに止め、人に知らせる。
  • 自動化は、自分が食い違った状態に陥っても、最新の正しい計画を当て直して戻れるようにする。戻れない状態は、試験の中で意図して作って確かめる。

悪い例と直した例。架空の DNS の計画を当てる自動化。名前は example.com、IP は説明用の範囲

# 悪い例 始めに一度だけ比べ、あとは無条件に書く
if plan.gen > store.applied_gen("api.example.com"):
    slow_work()                               # この間に他の書き手が進む
    store.put("api.example.com", plan.records)

# 直した例 書く時に比べ、空の記録を拒む
if len(plan.records) == 0 or len(plan.records) < 0.5 * current_count:
    alert("plan rejected: too few records"); return
ok = store.put_if("api.example.com", plan.records,
                  gen=plan.gen, only_if_applied_gen_lt=plan.gen)
if not ok:
    return                                    # もっと新しい計画が当たっている

# 掃除 当たっている計画は消さない
for p in store.plans_older_than(keep_gen):
    if not store.is_referenced(p.id):
        store.delete(p.id)

当てる前と後の名前の解決。架空の入口

$ dig +short api.example.com A
192.0.2.10
192.0.2.11
198.51.100.20

# 計画が消された後
$ dig +short api.example.com A
# 何も返らない。利用者はつなぐ先を失う
  • DNS の記録が空になると、手元に残った記録が期限を迎えた順に、利用者がつなげなくなる。この件で利用者が戻ったのも、DNS を戻した後、手元の記録が期限を迎えてからだった[1]。TTL は、壊れた時に広がる速さと、直した時に戻る速さの両方を決める。
  • 確かめた時と使った時の差の競合は、テストで滅多に出ない。この件も、まれな遅れが重なった時だけに起きた[1]。書き手を増やした時は、遅れた書き手が古い物を書く場面を、遅れを注入して試す。
緩和の策
  • 戻る時の仕事の山を、受け付けの段で絞る。待ち行列の長さに応じて受け付けを減らせば、時間切れのやり直しが積もる崩壊を避けられる[1]。再試行の待ちには、ゆらぎを入れた指数的な待ちを使う[3]。
  • 健全性の確かめで容量を外す仕組みには、一度に外せる量の上限を置く。確かめる側が揺れた時に、全部を外さない[1]。
  • 利用する側は、DynamoDB のグローバルテーブルのような複数の地域の写しを持てば、1つの地域の入口が引けなくても読み書きを続けられる[1]。
  • 自分の仕組みが、どの地域の、どの共通の仕組みに頼っているかを棚卸しする。この件では、ほかの地域の Redshift の問い合わせとコンソールのログインが us-east-1 に頼っていた[1]。
  • 確かめと書き込みが分かれた差分は、AIが書いたコードでもよく出る。並行に動く書き手がいる所の差分は、書く時に比べているかを読む。読み方は AIの出力を確かめる にある。競合の設計は A06 安全性を欠いた設計 にもある。

参照

  1. Summary of the Amazon DynamoDB Service Disruption in the Northern Virginia US-EAST-1 Region AWS、2025年10月。頁に公表の日付の記載は無い
  2. CWE-367 Time-of-check Time-of-use TOCTOU Race Condition MITRE
  3. Addressing Cascading Failures Site Reliability Engineering、Google