WSUS(Windows Server 2016/2019)で Windows 10 の「機能更新プログラム(Upgrades)」だけ同期が不安定になり、.cab は落ちるのに .esd だけダウンロード失敗する現象は、WSUS 側の設定不備よりも“通信経路で HTTP Range(バイト範囲要求)が壊れている”ことが原因になっているケースが多いです。本記事では、原因を .esd に絞って切り分ける具体手順と、現場で効く対処ポイントをまとめます。
症状の整理:Upgrades を有効にすると「.esd だけ」失敗する
まずは、よくある再現パターンを整理します。WSUS サーバー(Windows Server 2016/2019、WSUS 役割、内蔵 DB(WID)、空き容量十分、プロキシ未使用)で、製品に Windows 10、分類に Upgrades(機能更新) を選択すると、同期自体は進みます。しかし、機能更新に関連する配布ファイルのうち .esd だけがダウンロード失敗し、WSUS コンソール上は「この更新プログラムのファイルをダウンロードできませんでした」と表示されます。
アプリケーションログには イベント ID 364 が記録され、内容としては次のような趣旨が現れます。
- BITS が必要とする Range ヘッダー(バイト範囲要求)への対応が必要
- しかし、サーバーが必要な HTTP プロトコルをサポートしていない(またはそのように見える)
ここで重要なのは、download.windowsupdate.com が本当に Range 非対応という話よりも、途中の経路が Range を阻害している可能性を疑うべき、という点です。特に、前段にファイアウォールや中継機器(透過プロキシ、HTTP/HTTPS 検査、コンテンツフィルタ、キャッシュ装置など)がある構成では、.esd のような大きいファイルで症状が顕在化しやすくなります。
| 項目 | 典型的な状況 | ここから読み取れること |
|---|---|---|
| WSUS コンソール | 更新メタデータは取得できるが、ファイル取得で失敗 | 名前解決や基本的な通信は成立している可能性が高い |
| 失敗対象 | .cab は成功、.esd だけ失敗 | サイズ・転送方式(再開/分割)・中継機器の振る舞い差が怪しい |
| イベントログ | イベント ID 364、Range ヘッダー関連の文言 | HTTP Range が維持されていない状況の可能性 |
| 手動ダウンロード | ブラウザーでは落ちる/落ちないが揺れる | 「ブラウザーができる=BITS もできる」とは限らない |
なぜ「.esd だけ」落ちないのか:機能更新の配布方式と BITS の関係
.esd は、Windows 10 の機能更新(Feature Update)で利用されることが多いコンテナ形式の一つで、サイズが数 GB クラスになりやすいのが特徴です。対して .cab は相対的に小さなファイルが多く、ネットワーク的に“雑に通しても”成功してしまうことがあります。
WSUS が Microsoft 側の配布元からコンテンツを取得するときには、内部的に BITS(Background Intelligent Transfer Service)が関与し、転送の効率化・再開(レジューム)・分割取得などのために HTTP Range(バイト範囲要求)を活用します。ここが壊れると、次のような現象になりがちです。
- 数百 MB 程度までの更新(.cab 等)は「たまたま」成功する
- 数 GB の .esd で途中から失敗する、または最初から弾かれる
- エラー文言は「サーバーが必要な HTTP プロトコルをサポートしていない」など、“相手が悪い”ように見える
つまり、.esd だけ失敗という情報は、それ自体が強い手がかりです。WSUS の設定や MIME より先に、まずは “BITS が使う Range を、途中の装置が壊していないか”を検証するのが近道です。
最短で原因を絞る:WSUS DB から .esd の実体 URL(MUURL)を抜き出して直接検証する
この問題の切り分けで効くのが、WSUS DB から .esd の配布元 URL(Microsoft 側の実体 URL)を特定し、その URL に対して WSUS サーバー自身から 直接ダウンロードや Range テストを行う方法です。
狙いは明確で、次のどちらかを判定します。
- ネットワーク的に取れない(=URL への到達や Range が途中で阻害)
- ネットワーク的には取れるが、WSUS 同期(BITS)だけ失敗(=WSUS/BITS 側の問題)
DB 接続の前提:WID(内蔵 DB)か SQL Server かを確認する
WSUS は WID(Windows Internal Database)でも SQL Server でも動作します。内蔵 DB 環境(WID)の場合は、一般的に SUSDB というデータベース名で保持されています。
| WSUS の DB 形態 | 見分け方(例) | 接続の考え方 |
|---|---|---|
| WID(内蔵 DB) | 「Windows Internal Database」サービスが稼働 | 名前付きパイプで SUSDB に接続(sqlcmd / SSMS) |
| SQL Server | 外部 SQL インスタンスに WSUS が接続 | 通常の SQL Server と同様に接続 |
WID の場合でも、読み取り専用でクエリを投げるだけなら現場でよく行われます。更新(UPDATE/DELETE)など破壊的な操作は行わない前提で進めてください。
.esd を tbFile から探す:まずは“ファイル名で当たりを付ける”
WSUS DB のテーブル構成は環境差がありますが、質問の切り分けでよく使うのが tbFile です。まずは .esd を含むファイルを引っ掛けて、対象の FileId(または類似のキー)を把握します。
-- 例:.esd ファイルを一覧(新しいものから)
USE SUSDB;
SELECT TOP 200
FileId,
FileName,
Modified
FROM tbFile
WHERE FileName LIKE '%.esd%'
ORDER BY Modified DESC;
ここで、失敗していそうなタイミングの .esd を選び、次に配布元 URL を取り出します。環境によっては、URL 情報が tbFile ではなく、別テーブル(例:tbFileLocation の Url 列など)に格納されています。
MUURL(配布元 URL)を取り出す:tbFileLocation 等を参照する
次のクエリは一例です。実際の列名が異なる場合もあるため、まずは tbFileLocation の列を確認し、URL を保持している列(Url / FileUrl / Location など)を特定してください。
-- 例:FileId をキーに配布元 URL を取得
USE SUSDB;
SELECT
FileId,
Url
FROM tbFileLocation
WHERE FileId = 123456; -- ここを対象の FileId に置き換え
取得できた URL(= MUURL / Microsoft 側の配布 URL)を、次の検証に使います。
“直接ダウンロード”で一次判定:通信経路として取れるか
まずは WSUS サーバー上で、URL に対して普通にダウンロードができるか試します。これは「DNS やルーティング、TLS/証明書、基本的な通信」が成立しているかの確認です。
# PowerShell(管理者)例:.esd をそのまま保存
$uri = "(ここに MUURL)"
$out = "C:\Temp\test.esd"
Invoke-WebRequest -Uri $uri -OutFile $out -UseBasicParsing
ここで失敗する場合は、まずネットワーク(名前解決・経路・FW ルール・HTTPS 検査・レピュテーションフィルタ等)の問題を疑えます。一方で、これが成功しても、まだ安心できません。次が本丸です。
最重要:Range(バイト範囲要求)が通るかを必ず確認する
「ブラウザーや通常のダウンロードは成功するのに、WSUS 同期(BITS)だけ失敗する」というケースで、最も多い落とし穴がここです。“普通の GET は通るが、Range を付けた GET だけ壊れる”という状況は、次世代ファイアウォールや SSL/HTTP 検査装置、キャッシュ装置などで起こり得ます。
PowerShell で Range テスト(HTTP 206 が返るか)
以下は、先頭 1KB だけを Range で要求し、ステータスコードと Content-Range を確認するテストです。
$uri = "(ここに MUURL)"
try {
$r = Invoke-WebRequest -Uri $uri -Method Get -Headers @{ Range = "bytes=0-1023" } -UseBasicParsing
"StatusCode : {0}" -f $r.StatusCode
"Accept-Ranges : {0}" -f $r.Headers["Accept-Ranges"]
"Content-Range : {0}" -f $r.Headers["Content-Range"]
} catch {
$_.Exception.Message
}
期待する結果の目安は次の通りです。
| 確認ポイント | 望ましい結果 | 望ましくない例 | 読み取れること |
|---|---|---|---|
| StatusCode | 206(Partial Content) | 200(OK)/ 403 / 416 等 | Range が有効かどうかの最重要指標 |
| Content-Range | bytes 0-1023/(総サイズ) | 空 / 返らない | 途中で Range が落とされている可能性 |
| Accept-Ranges | bytes | none / 空 | サーバー(または中継)が Range を許可していない疑い |
StatusCode が 200 になる場合、要求側は Range を付けているのに、途中で削られて “普通の GET” にされている可能性があります。これは BITS 的には致命的で、WSUS の .esd 取得が失敗しやすくなります。
curl が使える環境ならさらに簡単(ヘッダーだけ見る)
Windows Server 2019 以降や環境によっては curl が利用できることがあります。ヘッダーだけ確認したい場合は次の方法が手軽です。
curl -I -H "Range: bytes=0-1023" "(MUURL)"
出力の 1 行目が HTTP/1.1 206 になっているか、また Content-Range が付くかを確認します。
Range が通らないと分かったら:ネットワーク経路の“どこ”で壊れているかを特定する
Range テストで 206 が返らない場合、WSUS の設定をいくら触っても改善しないことが多いです。先にネットワーク側の疑いを潰します。ポイントは「通信が通るか」ではなく、“Range が維持されているか”です。
比較テストが強い:別経路から同じ MUURL を叩く
次のような比較ができると、原因特定が一気に進みます。
- WSUS サーバー(問題の経路)から Range テスト → 206 が出ない
- 同一ネットワーク内の別 PC から Range テスト → 206 が出る/出ない
- ファイアウォールを迂回できる検証環境(テザリング等)から Range テスト → 206 が出る
この比較で、“経路依存”が証明できれば、ネットワーク担当に話が通りやすくなります。イベント ID 364 の文言だけだと「WSUS の問題では?」で止まることが多いため、Range 要求の結果(206/200)を添えて共有するのが有効です。
Range を壊しやすい機能の例(ファイアウォール/UTM/中継機器)
製品名に依存しない“地雷機能”はだいたい共通しています。次の表をチェックリストとして使ってください。
| 機能(例) | 起こり得る影響 | 対処の方向性 |
|---|---|---|
| HTTP/HTTPS インスペクション(SSL 復号) | ヘッダー改変・プロトコル変換で Range が欠落 | Microsoft 更新配布ドメインを検査対象から除外 |
| コンテンツフィルタ/AV スキャン | 大容量ファイルでタイムアウト・分割転送失敗 | サイズ閾値やスキャン対象の除外、タイムアウト緩和 |
| キャッシュ/最適化(WAN 最適化) | Range をまとめて取得し直し、BITS と相性悪化 | Windows Update 系 URL のキャッシュ無効化 |
| セキュリティ対策としての Range 制限 | Range リクエスト自体をブロック/削除 | 特定宛先だけ許可、または機能を無効化 |
| 透過プロキシ(意図せず有効) | “プロキシなし”のつもりでも経路上で変換 | 経路設計の見直し、例外ルール、バイパス経路 |
特に .esd のような大きいファイルは、機器側の「大容量ダウンロード制御」「ストリーミング検査」「レピュテーション判定」などの影響を受けやすいです。通信が 80/443 で通っているだけでは不十分で、Range を含む HTTP の振る舞いが崩れていないかを確認する必要があります。
「手動だと落ちる/落ちない」揺れがある場合の考え方
ブラウザーの手動ダウンロードが成功したり失敗したりする場合でも、次の点で判断を誤りやすいです。
- ブラウザーは BITS と同じ挙動をしない(Range を使う/使わない、再試行の仕方が違う)
- 途中の装置が “条件付き” で挙動を変える(ファイルサイズ、同時接続数、時間帯、帯域制御)
- 一度キャッシュに載ると成功する(または逆にキャッシュが壊れて失敗する)
そのため、手動の成否よりも、Range テストで 206 が安定して返るかを基準にしてください。ここが安定しない限り、WSUS 側の再同期や reset をしても再発しやすくなります。
WSUS サーバー側の確認ポイント:ネットワーク以外で潰すべき項目
Range が通る(206 が返る)のに WSUS の同期だけが失敗する場合は、WSUS/BITS 側の切り分けに移ります。逆に、Range が通らない場合はネットワークを先に直すのが基本です。
WinHTTP のプロキシ設定が残っていないか
「プロキシなし」のつもりでも、WinHTTP 側に設定が残っているケースがあります。WSUS の通信は WinHTTP の影響を受けるため、念のため確認します。
netsh winhttp show proxy
もし意図しないプロキシが入っている場合は、環境ポリシーに沿って解除・例外設定を検討してください(勝手にリセットせず、ネットワーク設計と整合を取るのが安全です)。
BITS サービスの状態とジョブ詰まり
BITS が停止していたり、ジョブが異常に滞留していると、ダウンロードに失敗しやすくなります。まずは状態確認を行います。
# BITS サービス状態
Get-Service BITS
# ジョブ一覧(管理者権限が必要な場合あり)
Get-BitsTransfer -AllUsers | Select-Object DisplayName,JobState,BytesTotal,BytesTransferred
ジョブが大量に詰まっている場合は、原因(通信・ストレージ・アクセス権)を確認した上で整理します。いきなり全削除すると状況把握が困難になるため、まずは「どの URL で失敗しているか」をログと合わせて追うのがおすすめです。
WSUS コンテンツの整合性:wsusutil reset は“最後の仕上げ”
ネットワークが原因だった場合、経路を直しても WSUS 側に「取り損ね」が残ります。その後の回復として wsusutil reset が有効です。これは不足・破損しているコンテンツを再ダウンロードさせる処理で、.esd の再取得にもつながります。
cd "C:\Program Files\Update Services\Tools"
wsusutil.exe reset
wsusutil.exe checkhealth
ただし、reset はダウンロード量が大きくなりやすく、時間・帯域・ディスク消費の影響があります。Range が通っている状態を作ってから実行するのが鉄則です(通っていない状態で繰り返すと、失敗ログだけが増えて疲弊します)。
ログの見どころ:失敗した .esd の URL とエラー文言を押さえる
原因切り分けでは「どの URL の、どの要求が失敗したか」を押さえるのが重要です。WSUS 関連のログは複数あり、環境差もありますが、代表的な場所は次の通りです。
| ログ/場所 | 主な用途 | 見るべきポイント |
|---|---|---|
| イベントビューアー(アプリケーション) | WSUS のダウンロード失敗概要 | イベント ID 364、エラー文言、タイムスタンプ |
| WSUS ログ(Update Services の LogFiles 配下) | 同期・ダウンロードの詳細 | 失敗したファイル名や URL、HTTP 関連のエラー |
| BITS クライアントの運用ログ | BITS の転送エラー詳細 | HTTP ステータス、再試行、タイムアウトの有無 |
質問の状況に近いケースでは、WSUS ログ(例:SoftwareDistribution.log など)に、失敗した .esd の URLと、Range header に関する同様のエラーが残っていることがあります。これを根拠として提示できると、「WSUS の設定ではなく経路の問題」だと説明しやすくなります。
IIS の MIME 設定はどこまで効く?(効くケース/効かないケース)
「.esd の MIME タイプを application/octet-stream に設定する」といった対処が挙がることがあります。これは、クライアントが WSUS から .esd を配布してもらうフェーズでは有効に働く可能性があります。
一方で、今回のように WSUS サーバー自身が Microsoft から .esd を取得できない(同期・ダウンロードで失敗)状況では、IIS の MIME 設定を変更しても改善しないケースが多いです。理由は単純で、落ちていないのは WSUS からクライアントへの配布ではなく、Microsoft → WSUS の取得だからです。
とはいえ、将来的にクライアント配布で 404/拡張子関連の問題が出る可能性もあるため、運用の整備としては次の確認が有用です。
| 確認項目 | 推奨 | 補足 |
|---|---|---|
| .esd の MIME | application/octet-stream | WSUS → クライアント配布で問題があるときに効きやすい |
| WSUS の IIS 変更 | 必要最小限 | 同期失敗の根本原因がネットワークの場合、ここを触っても治らないことが多い |
おすすめの切り分け手順:この順番でやると遠回りしない
.esd だけ落ちない問題は、順番を間違えると「WSUS 再構築」「IIS いじり」「DB メンテ」などの重い作業に走りがちです。現実的に成果が出やすい順番をまとめます。
- WSUS DB から .esd の MUURL を特定する(tbFile → URL)
- WSUS サーバーから 通常のダウンロードを試す(到達性の確認)
- 同じ WSUS サーバーから Range テスト(206 が返るか)を実施
- 可能なら別経路(別端末/別回線)でも Range テストし、経路依存を証明
- ファイアウォール/中継機器の機能(検査・キャッシュ・Range 制限)を見直し、Microsoft 更新配布系を除外
- Range が安定したら wsusutil reset で取り損ねを回収し、同期を回復
- 最後に IIS の MIME など「配布フェーズ」の設定を必要に応じて整備
この流れで進めると、「ネットワークが原因だったのに WSUS を触り続けていた」という最悪の遠回りを避けやすくなります。
よくある疑問と答え(現場向け)
download.windowsupdate.com が Range 非対応って本当?
多くのケースでは、配布元そのものが非対応というより、途中の装置が Range を落としたり、別の応答に変換していることで “非対応に見える” 状態になっています。Range テストで 206 が返らない場合は、まず経路を疑うのが合理的です。
.cab は落ちるのに .esd だけ落ちないのはなぜ?
.esd はサイズが大きく、BITS が再開や分割取得のために Range を使いやすい一方、.cab は小さくて一括取得でも成功しやすいからです。中継機器が「大容量だけ別扱い」する構成だと、.esd だけが狙い撃ちで失敗します。
“プロキシなし”なのにプロキシが原因になることはある?
あります。明示的プロキシを設定していなくても、透過プロキシ、SSL インスペクション、WAN 最適化、キャッシュ装置などが経路上にあれば、実質的にプロキシと同様の影響が出ます。だからこそ、MUURL に対する Range テストが強力です。
ネットワークが直ったら、WSUS 側でやるべきことは?
まずは同期を再実行し、必要に応じて wsusutil resetで不足コンテンツを回収します。その後、アプリケーションログ(イベント ID 364)が収束するか、WSUS ログで同一 URL のエラーが消えるかを確認すると、再発防止の判断がしやすくなります。
まとめ:.esd の MUURL と Range(206)で“犯人”が見える
WSUS(Windows Server 2016/2019)で Windows 10 の Upgrades(機能更新)だけ .esd が落ちないとき、最短で効くのは 「.esd の実体 URL を DB から抜く → Range テストで 206 を確認する」という切り分けです。ここで 206 が返らないなら、WSUS の設定より先に、ファイアウォールや中継機器の HTTP/HTTPS 検査・キャッシュ・Range 制限を疑うのが王道です。
逆に 206 が問題なく返るなら、BITS/WSUS 側(ジョブ詰まり、コンテンツ整合性、reset での回復)に集中できます。.cab が落ちていることで安心せず、.esd という“サイズと転送方式が違うファイル”を軸に切り分けることで、短時間で原因に辿り着ける確率が上がります。

コメント