NEXCO中日本 2025年 改修の後のETCの広域障害

ETCカードを通してよいかの判定データを料金所へ配る途中で、送るたびに作る宛先の情報が消されずにたまり、判定データの領域まで書き込んで壊した。正常なカードの一部が通行不可と判定され、最大106か所の料金所でバーが開かなかった。改修した側を先に疑って復元したため、翌日0時の自動配信で同じ障害が再び起き、応急復旧まで約38時間かかった。

攻撃ではなく、システムの不具合から始まった障害です。NEXCO中日本が設けた有識者の危機管理検討委員会の2025年4月18日、4月22日、6月23日の資料、5月2日と7月31日の NEXCO中日本の発表、8月5日に国土交通省の部会へ出された報告に沿って書いています。原因のプログラムを直す本復旧の作業は2025年7月31日16時に終わったと発表されました[6]。不具合の仕組みは委員会の資料により、報道によりません。改修を請け負った会社の名前、プログラムの言語や作り、4月5日の改修で何を変えたかは資料に無い。2026年11月時点の公開資料で書いています。

要点

  • 2025年4月6日0時半ごろから、1都7県の17路線106か所の料金所でETCレーンが通れなくなり、2km以上の渋滞が10か所で起きた。
  • 原因は、広域管理システムから地域管理システムへの配信で、送った宛先データを消す機能が無かったこと。たまった宛先データが判定データを侵食した。工場の再現試験で同じ壊れ方が出て、原因と確定された。
  • 配信は、深夜割引の見直しに向けて構築中のシステムを使っていた。前日の4月5日には地域管理サーバの改修作業があった。
  • 初めは改修した地域管理システムを疑って復元し、手動の試験配信では障害が出なかった。翌日0時の自動配信で再発し、広域管理システムからの配信データの破損が分かった。
  • 広域の障害を想定したマニュアルが無く、バーを閉じたまま1台ずつ止めて後日の支払いを案内したことが渋滞を広げた。今は、バーを開け、料金を取れないときは取らない決まりになった。

何が起きたか

4月5日の改修の後、6日0時の配信で障害が起き、地域管理システムの復元の後も7日0時の配信で再発し、7日14時に手動の配信で応急復旧し、7月31日に本復旧した 4月5日 21時まで 地域管理の改修 4月6日 0時半 0時の自動配信の後 38か所で障害 4月6日 5時 地域管理を疑い 復元を始める 4月6日 13時半 障害の料金所で バーを開ける 4月6日 18時 復元を終え手動で 試験配信し異常なし 4月7日 0時 自動配信で再発 1時半 最大106か所 4月7日 3時 広域管理からの データの破損を確認 4月7日 14時 手動の配信で 応急復旧 6月23日 再発防止策と 危機対応マニュアル 7月31日 16時 本復旧の作業を 完了 始まりと発覚はどちらも4月6日0時半ごろ。発生から応急復旧まで約38時間
図1 委員会の資料と発表にある経緯
日時資料と発表の内容
2025年4月5日 21時まで地域管理サーバの改修作業を実施[2]
4月6日 0時ETCの課金に必要なデータを自動で配信[2]
4月6日 0時半ごろ東京、八王子、名古屋の各支社の管内の料金所で ETC が使えなくなる。障害は38か所。同時に本部の体制を立てた[2]
4月6日 0時40分から料金所ごとの判断で、ETCレーンの閉鎖、止まった車のカード番号を控えての後日の課金、後日の精算のチラシ配りを順に始める。1時20分にスマートICを閉鎖[2]
4月6日 4時から5時地域管理システムを中心に調べ始め、5時に原因を地域管理システムと想定して復元を始める[2]
4月6日 12時43分から13時30分発進制御バーを開ける方針を決め、13時30分から障害の料金所でバーを開け、その場では料金を取らずに通す[2]
4月6日 18時地域管理システムの復元が終わり、データを手動で試験配信して、料金所で障害が無いことを順に確かめる。18時30分に緊急の記者会見[2]
4月7日 0時自動配信で、再び不具合が起きる。1時30分ごろに最大の106か所[2]
4月7日 3時広域管理システムからの配信データの破損を確かめる。8時に手動での対応ができることを確かめ、12時に手動でデータを配信[2]
4月7日 14時応急復旧の作業が終わり、全車両の通行を確かめる。発生から約38時間[2]
4月18日、22日有識者の委員会の第1回と第2回。22日に原因の究明の結果と当面の対策をまとめる[1][3]
5月2日障害の料金所の出口を使い支払った人へ、利用額と同じ額を還元すると発表[5]
6月23日NEXCOの3社で再発防止策と、広域のETCの障害の危機対応マニュアルを決める[4][8]
7月1日、7月9日改正した供用約款を7月1日から適用。7月9日に、ETCの障害で料金の徴収が難しい車から料金を取らないとする告示の改正を公布、施行[7]
7月28日から31日7月28日16時から本復旧の作業。期間中は ETC レーンのバーを開けて運用し、31日16時に完了[6]
  • 障害が起きた範囲は、最大で東京、神奈川、静岡、山梨、愛知、三重、岐阜、長野の1都7県、17路線106か所[2]。
  • 入口では、ETCレーンをそのまま使った料金所が37か所、閉じて一般レーンで通行券を出した料金所が49か所あった。出口の86か所は、止まった車の後日の課金、閉鎖とチラシ配りを経て、本部の指示でバーを開けた。スマートICの20か所は、まず閉鎖した[2]。
  • 委員会は、深夜割引の見直しの運用開始を2025年7月ごろとしていた予定について、再発防止の作業を踏まえて工程を改めて精査するとした[3]。

起きた仕組み

カードの判定データは、料金システムから統括、広域管理、地域管理、料金所サーバを経てレーンへ毎日配られ、広域管理から地域管理への配信で壊れた センター 事務所と料金所 料金システム 統括システム 広域管理 宛先を消さない 地域管理 複数ある 料金所サーバ 壊れた判定を受信 ETCレーン バーが開かない この経路は深夜割引の見直しに向けて構築中のシステム。課金データは既存の別の経路で送られる 広域管理から地域管理へ送る所で、判定データが壊れた 正常なカードの一部が通行不可と判定され、レーンでバーが開かなかった
図2 カードの判定データの流れと、壊れた所

ETCレーンは、カードが使えるかをその場ですぐ判定するため、個々のカードの判定データを毎日すべての料金所のサーバへ送っている[3]。課金のデータは既存のシステムで送られ、判定のデータは深夜割引の見直しに向けて構築中のシステムで配られていた[3]。

システムの間でデータを送るときは、送るたびに、どのシステムへ送るかの宛先データが作られ、宛先データと判定データを組にして送る。宛先データは送った後に消されるはずだった。広域管理システムには、この宛先データを消す機能が無かった。消されない宛先データがたまって領域を圧迫し、判定データを侵食して壊した[3]。壊れた判定データが各料金所のサーバへ送られ、正常なカードの一部が通行不可と判定された[3]。工場での再現試験で同じ壊れ方が出たことから、これが原因と確定された[3]。

正常なら送るたびに宛先データが消える。今回は前回の宛先データがたまり、判定データの領域まで食い込んだ。直した後は送るたびに消し、上限を超えたら警告と配信の停止をする 正常 今回の宛先 カードの判定データ 今回 前回 前回 今回の宛先 判定データ 判定データの領域へ食い込み、壊す 直した後 今回の宛先 カードの判定データ 1 送り終えるたびに前回の宛先を消す 2と3 たまり具合が上限を超えたら警告し、自動配信を止める 宛先情報の領域 判定データの領域
図3 送るデータの中身。4月22日の資料のデータの破損の図と対策の図をもとに描いた。2と3は検討するとされた

形としては、決まった大きさの領域の外へ書き込む CWE-787 にあたる[9]。1回の送信では表に出ず、送る回数が重なって初めて壊れる。次は架空の配信処理で、仕組みだけを示す。

悪い例。架空の配信処理。送るたびに宛先を前回の後ろへ足し、消さない

// 架空の例。領域の大きさも作りも本物ではない
const HEADER_AREA = 64;
const msg = Buffer.alloc(HEADER_AREA + BODY_SIZE);
let headerEnd = 0;

function send(dest, cards) {
  cards.copy(msg, HEADER_AREA);
  headerEnd += msg.write(dest.id + ";", headerEnd);
  // headerEnd が HEADER_AREA を超えると、判定データの上に書く
  transmit(dest, msg);
}

直した例。送るたびに初期化し、境界と中身を確かめてから送る

function send(dest, cards) {
  const header = Buffer.from(dest.id);
  if (header.length > HEADER_AREA) return stopAndAlert("header_overflow");
  msg.fill(0, 0, HEADER_AREA);
  header.copy(msg, 0);
  cards.copy(msg, HEADER_AREA);
  if (!sameDigest(msg.subarray(HEADER_AREA), cards)) return stopAndAlert("body_mismatch");
  transmit(dest, msg);
}

委員会の資料の対策も同じ3段である。前回の宛先データを通信が終わるたびに消すプログラムを適用し、加えて、宛先データの状態を常に見て、設定値を超えたら警告を出す機能と、自動配信を止める機能の追加を検討するとした[3]。応急復旧の後の配信は、配信のたびにメモリを消す手動の作業で回していた[3]。

改修した側を先に疑った

前日に改修したのは地域管理サーバだった。6日の朝は地域管理システムを中心に調べ、5時から復元し、18時に復元を終えて手動で試験配信すると障害は出なかった[2]。ところが7日0時の自動配信で再発し、3時に広域管理システムからの配信データの破損が分かった[2]。直近の変更を疑うのは正しい初手だが、変更した部品だけを直しても、配信の元が同じなら同じ壊れたデータがまた届く。手動の試験配信と、0時の自動配信は同じ条件ではなかった。

改修が原因、とだけ言うと外れる

4月5日の改修は地域管理サーバの作業で、原因と確定されたのは広域管理システムに宛先データを消す機能が無かったことである[2][3]。6月23日の資料は障害の要因の1つを「システム改修 今回の障害」と書くが[10]、4月5日の改修で何を変え、それが消す機能の欠落とどうつながるかは、公開の資料に無い。

閉じたままのバー

判定データが壊れて止まったのは、カードの判定である。ところが料金所では、広域の障害のマニュアルが無く、従来のマニュアルに沿って料金所ごとに判断した[3]。バーを下ろしたまま、止まった車に1台ずつ後日の支払いを案内し、渋滞を招いた[4]。バーを開けたときも、料金表示器の誤った表示による混乱を避けようとして ETC の通信を切ったため、後日の精算が要った[3]。通信を続けた料金所では課金のデータが正常だったと後で分かり、通信を切った料金所では請求が難しかった[5][7]。

どこで止められたか

作る、試す、配る、気付く、絞る、運用するの6段それぞれの下に、止める仕組みを置く 1 作る 宛先を消さない 2 試す 重ねると壊れる 3 配る 壊れたまま全域 4 気付く 広域と分からない 5 絞る 別の所を直す 6 運用 バーを閉じた 初期化 送るたびに消す 境界を確かめる 本番の形 同じ宛先の数で 続けて配る試験 配る前 中身を検査し 超えたら止める 発令の目安 異常停止の数で 本部を立てる 変更の一覧 直近の改修を 全部並べる 倒し方 バーを開け 通信は続ける 1が根本。2と3は壊れたデータを外へ出さない網。4から6は、出た後の被害を小さくする備え
図4 障害が広がる6段と、それぞれで止める仕組み
段この件で資料にあること止める仕組み
1 作る広域管理システムに、送った宛先データを消す機能が無かった[3]送るたびに使う領域を初期化し、書く前に境界を確かめる。前回の宛先データを消すプログラムが適用された[3]
2 試す工場の再現試験で同じ壊れ方が出た。それより前の試験の中身は資料に無い[3]本番と同じ宛先の数と回数で、続けて配る試験を改修の前に通す
3 配る壊れた判定データが、そのまま各料金所のサーバへ送られた[3]宛先データのたまり具合が設定値を超えたら警告し、自動配信を止める。資料では検討とされた[3]。配る前に中身を元と照合する
4 気付くETCの障害を対象にした危機管理の体制の発令基準が無く、初動は限られた体制だった[3]同じ支社の管内の2か所以上の料金所で、1か所あたり30分に10台の異常停止を、広域の障害を疑う目安にした[3]
5 絞る原因の特定に時間がかかり、応急復旧まで38時間。改修の時に広域の障害が起きる想定の備えが無かった[3]改修の時は作業の日程と中身を関係するベンダーと NEXCO の3社で共有し、24時間の連絡の窓口を置く。続報に直近の改修の内容を入れる[4][8]
6 運用バーを下ろしたまま1台ずつ案内し、バーを開けたときは通信を切った[3][4]バーを開け、料金表示器を覆い、ETCの通信は続ける。料金の徴収に要る情報が取れないときは取らない[3][4]

1 作る。根本の段

送るたびに作る作業用のデータを、送った後に消すのは、使う側が覚えておくべき後始末である。後始末に頼る作りは、1か所の書き忘れで静かに壊れる。送るたびに領域を新しく作るか初期化し、書く前に領域の大きさと比べる形にすれば、消し忘れても判定データの側へは届かない。境界の確かめ漏れが読み出しの側で起きた例は Heartbleed 2014年 にある。

2と3 試す、配る。壊れたデータを外へ出さない

この不具合は、1回の送信では出ず、たまって初めて出る。小さな試験で1回送って確かめても見つからない。本番と同じ宛先の数で、日をまたいで続けて配る形で試す。AIに書かせた配信の処理を確かめるときも、1回の正常な動きを見て終わりにせず、繰り返しと境界の値で試す。確かめ方は AIの出力を確かめる にある。

配る側では、作ったデータを送る前に、元のデータと照合し、合わなければ止める。全域へ一度に配らず、一部の地域へ先に配って確かめる手もある。設定や判定のデータを全域へ一度に配って止めた例は CrowdStrike 2024年 にある。

4と5 気付く、絞る

危機対応マニュアルは、改修のときに起こりうる障害を、改修の中身と範囲に応じてあらかじめ想定し、対策を講じ、それを超えたときの応急復旧の方法も決めておくとした[8]。第2報からは、直近の点検と改修の内容を入れて共有する[8]。改修した部品を疑うときも、その部品へデータを渡す上流と、同じ時期に動き出した仕組みを一覧に並べる。原因が確かめられるまでは、壊れたデータを配る自動の処理を止め、手で配る。この件の応急復旧も手動の配信だった[3]。

6 運用。失敗した時にどちらへ倒すか

認可の確認が失敗した時は拒否へ倒すのが原則である。A10 例外的な状況への不適切な対応 の「失敗した時に開く」にある。料金所のバーは逆で、判定データが壊れたときに閉じると、正しい利用者の通行と、本線の交通そのものを止める。再発防止策は、交通の流れを止めないことと、料金を取る情報が取れないときは取らないことを基本の方針にした[4]。そのために国の告示が改められ、ETCの障害で円滑な徴収が難しい車を、料金を取らない車に加えた[7]。失敗した時の倒し方は、守る対象ごとに先に決めて文書にしておく。

通信を切らずにバーを開けた料金所では、課金のデータが正常に残った[5]。止まったのはカードの判定で、課金の経路は別だった[3]。どの部分が壊れ、どの部分が生きているかで、運用を分ける。

守り方

根本の直し
  • 送るたびに作るデータは、送るたびに新しい領域へ作るか初期化する。消す処理を後始末に任せない[3]。
  • 決まった大きさの領域へ書く前に、必ず大きさと比べる。超えたら書かずに止めて知らせる[9]。
  • 配る前に、作ったデータを元のデータと照合する。合わなければ配らない。
緩和の策
  • たまり具合や件数を常に見て、設定値を超えたら警告し、自動配信を止める[3]。
  • 改修の前に、本番と同じ宛先の数と回数で続けて配る試験を通す。一部の地域へ先に配ってから全域へ広げる。AIの出力を確かめる
  • 改修の日程と中身を関係する会社のすべてで共有し、24時間の連絡の窓口を置く。本復旧の前に第三者の照査を受ける[4]。
  • 障害を疑う目安を数で決め、超えたら本部を立てる。続報に直近の改修を入れ、変更した部品の上流まで並べて疑う[3][8]。
  • 壊れたときの倒し方を対象ごとに決めておく。この件では、バーを開け、課金の通信は続け、取れない料金は取らない[4]。A10 例外的な状況への不適切な対応
  • 止める手段と再開の決まりを障害の前に決めておく点は、東京証券取引所 2020年 と同じである。

参照

  1. 広域的なETCシステム障害発生時の危機管理検討委員会 NEXCO中日本。委員会の設置、議事の概要、資料の一覧
  2. 広域的なETCシステム障害の発生事象について 事象概要報告 NEXCO中日本、第1回委員会の資料、2025年4月18日。時系列、障害の箇所数と推移、料金所の運用
  3. 広域的なETCシステム障害発生に対する当面の対策 NEXCO東日本、中日本、西日本、2025年4月22日。原因の究明の結果、データの破損の状況、当面の対策
  4. 再発防止策 NEXCO東日本、中日本、西日本、2025年6月23日
  5. ETCシステム障害時のご利用料金について お知らせ NEXCO中日本、2025年5月2日
  6. 7月31日16時をもってETCシステム障害の本復旧作業は完了しました NEXCO中日本、2025年7月31日
  7. 広域的なETCシステム障害発生に対する対策 報告 NEXCO中日本、2025年8月5日、国土交通省の審議会の資料2。料金の還元、供用約款の改正、告示の改正
  8. 広域的ETCシステム障害発生時の危機対応マニュアル NEXCO中日本、2025年6月
  9. CWE-787 Out-of-bounds Write MITRE
  10. 第3回委員会の資料 広域的なETCシステム障害発生時の危機管理検討委員会、2025年6月23日。料金システムで想定される障害の要因