Azure DevOpsパイプラインでdotnet workload install mauiが突然失敗する原因と対処法|MAUIワークロードのダウンロードエラー

Azure DevOps の YAML パイプラインで dotnet workload install maui が、昨日まで動いていたのに突然 40 分前後で失敗する――そんなトラブルは、YAML や .NET SDK を更新しても直らないことがあります。多くは「実行エージェント環境」「ネットワーク到達性」「キャッシュ破損」のどれか。本記事では最短で切り分け、安定化させる実務手順をまとめます。

目次

Azure DevOps パイプラインで起きる症状:dotnet workload install maui が突然失敗する

典型的には、Azure DevOps の YAML で DotNetCoreCLI@2 のカスタムコマンドを使い、MAUI ワークロードをインストールしています。

- task: DotNetCoreCLI@2
  displayName: 'Install MAUI workloads'
  inputs:
    command: custom
    custom: workload
    arguments: 'install maui'

これが数か月は問題なく動いていたのに、ある日から何も変更していないのに、約 40 分かかった後に失敗するようになります。失敗箇所は毎回同じではなく、次のような「ワークロード関連パッケージのダウンロード失敗」が例として出ます。

  • microsoft.maui.resizetizer.sdk(例:7.0.101)のダウンロード失敗
  • microsoft.android.sdk.windows(例:33.0.95)のダウンロード失敗

.NET SDK を 8.0.203 → 8.0.402 のように更新しても改善しない場合、原因は「SDK の古さ」ではなく、ワークロード配布元への到達性(ネットワーク/プロキシ/サービス側)、またはキャッシュ破損、あるいは実行環境の変化にあることが多いです。

「YAMLを変えていないのに壊れる」主な理由

dotnet workload install は、MAUI を使うためのワークロード(実体はマニフェストと複数のパック)をネットワーク越しに取得します。つまり、パイプライン定義が同じでも、外部要因で結果が変わり得ます。

変わるもの(YAML無変更でも起きる)現場でよくある変化失敗につながるポイント
Microsoft-hosted エージェントの VM イメージwindows-latest などのラベルは、中身の更新が継続的に入るプリインストールされる SDK/ツール/証明書ストア/ネットワーク設定が変わる
ワークロードのマニフェスト/パック配布状況CDN 側の一時的な不調、ミラーの切替、帯域制限「特定パッケージだけ落ちる」「時間帯で成功率が変わる」など
社内ネットワーク(Self-hosted の場合)プロキシの変更、TLS/中間証明書更新、回線品質の劣化巨大パッケージの途中切断や、SSL 検査での失敗が増える
キャッシュの整合性(Self-hosted で顕著)途中まで落ちたファイルが残る、ディスク不足、ウイルス対策のロック以降の実行でも同じ場所で失敗し続けることがある
利用される .NET SDK の選択global.json により意図せず古い SDK が選ばれる「SDK を更新したつもり」が、実際は更新されていない

最初に確認する:Microsoft-hosted か Self-hosted か

切り分けの最短ルートは、まずどこで実行されているかを確定させることです。原因の当たりどころが大きく変わります。

項目Microsoft-hosted エージェントSelf-hosted エージェント
実行環境ジョブごとに新しい VM。実行後は破棄される同じマシン/VM に継続してジョブが乗る
失敗の典型外部サービスやネットワーク経路の揺らぎ、VM イメージ更新の影響プロキシ/ファイアウォール/証明書/回線、ディスク、キャッシュ破損
再現性時間帯・リージョン・混雑で変動しやすい環境が固定されるぶん、原因を潰せば安定しやすい
対処方針ログで URL/失敗点を特定し、固定化(イメージ/SDK/ワークロード)とリトライ設計ネットワーク設定の見直し、キャッシュのクリア/修復、端末の健全性確保

まずは「実行環境」と「実際に使われている SDK」をログに出す

「更新したのに直らない」を潰すため、インストール直前に次を出力しておくと後が楽です。

- powershell: |
    dotnet --info
    dotnet --list-sdks
    dotnet --version
    dotnet workload --info
  displayName: 'Dump .NET info'

global.json があるリポジトリでは、パイプライン上に新しい SDK を入れても、コマンド実行時に古い SDK が選ばれることがあります。まず「実際に何が動いているか」を確定させてください。

原因を見える化する:--verbosity detailed で落ちる箇所を特定

ワークロードインストールの失敗は、表面上は「Downloading xxx failed」だけでも、裏でどのフィード/URL から取ろうとして、どのタイミングで失敗したかが分かると原因が一気に絞れます。まずは詳細ログを有効化します。

- task: DotNetCoreCLI@2
  displayName: 'Install MAUI workloads (detailed)'
  inputs:
    command: custom
    custom: workload
    arguments: 'install maui --verbosity detailed'

さらに踏み込む場合は --verbosity diagnostic にします。CI のログが増えるので、最初は detailed で十分です。

ダウンロード失敗の定番原因と、現場で効く対処

ネットワーク経路の揺らぎ(CDN/プロキシ/SSL検査)

MAUI 関連のパックはサイズが大きく、ダウンロード途中で切れると 30〜40 分といった長い時間を使った後に失敗しがちです。特に Self-hosted で企業ネットワーク配下の場合、次の要因が直撃します。

  • プロキシ設定が必要なのに未設定(または最近変更された)
  • SSL インスペクションで証明書チェーンが変わり、信頼できない状態になった
  • 外向き通信の帯域制限/アイドルタイムアウトが厳しい
  • 一部の配布先ドメインだけ許可されておらず、パックの取得に失敗する

対処としては、まず詳細ログに出てくる取得先を見て、ネットワークチームが追える形(どのドメイン/ポートが必要か)に落とし込みます。Self-hosted なら、同じマシンで PowerShell から手動で dotnet workload install maui を実行し、同じ失敗が再現するかも重要な判断材料です。

途中まで落ちたパックによる「キャッシュ破損」

ネットワークが一瞬でも落ちると、ダウンロード途中のファイルが残り、以降の実行で何度も同じ場所で失敗することがあります。Self-hosted で「昨日まで OK、今日からずっと NG」になったときは、まずこれを疑います。

定番の手当は次の順番が安全です(影響範囲が小さいものから)。

  1. NuGet のローカルキャッシュをクリアする
  2. workload の repair を実行する
  3. 必要なら uninstall → clean → install をやり直す
# 1) NuGet キャッシュのクリア
dotnet nuget locals all --clear

# 2) インストール済みワークロードの修復

dotnet workload repair

# 3) それでもダメなら(影響大なので専用エージェント推奨)

dotnet workload uninstall maui
dotnet workload clean --all
dotnet workload install maui --verbosity detailed

注意:dotnet workload clean --all は「全 SDK 版数」にまたがってコンポーネントを削除します。Self-hosted で複数プロジェクトが同居している場合は、ビルド専用マシン/専用エージェントで実施するのが安全です。

NuGet ソースの問題(認証・優先順位・ミラー)

企業環境では、nuget.config に社内フィードが追加されていたり、外部(nuget.org)がミラー経由になっていたりします。ここで認証が切れる/優先順位が変わると、ワークロード取得が不安定になります。

切り分けポイントは次のとおりです。

観察できる症状まず疑うこと優先する対処
社内だけ失敗し、個人回線では成功するプロキシ/SSL 検査/外向き許可ネットワーク設定の見直し、必要ドメインの許可
特定フィードが落ちた時だけ失敗する単一ソース依存、フェイルオーバー不足--ignore-failed-sources や複数 --source の検討
認証が必要なフィードを参照しているCI で対話認証できないAzure DevOps の認証タスク/サービス接続の見直し

とくに --ignore-failed-sources は「一部ソースの障害を警告扱いにする」オプションです。複数ソースがあり、代替ソースが有効なケースで効きます。単一ソースしかない場合は根本解決になりません。

Microsoft-hosted エージェントの「実行環境が変わった」問題

Microsoft-hosted ではメンテナンスと更新が自動で行われます。windows-latest のようなラベルを使っていると、VM イメージ更新により、ある日突然ツール構成が変わることがあります。

再現性を上げるための実務的な対処は次の 2 つです。

  • VM イメージを固定する:windows-latest ではなく windows-2022 など明示的なイメージに固定する
  • .NET SDK を固定する:UseDotNet@2 で SDK バージョンを指定し、ログで dotnet --version を確認する
pool:
  vmImage: 'windows-2022'

steps:

* task: UseDotNet@2
  displayName: 'Install .NET SDK'
  inputs:
  packageType: 'sdk'
  version: '8.0.402'

「SDK を更新したのに直らない」ケースでも、実際は別の SDK が選択されていることがあります。必ず dotnet --version を出して確認してください。

workload-set と manifests の違いを理解して「ワークロードを固定化」する

.NET 8.0.400 以降、ワークロードはworkload-set(ワークロード一式にバージョンを付ける考え方)で固定できるようになりました。CI では「毎回最新に追随」よりも、「同じものを再現できる」方がトラブルが減ります。

  • dotnet workload --version:現在のワークロードセット版数を表示
  • dotnet workload config --update-mode workload-set:workload-set モードに切替
  • global.json の workloadVersion:リポジトリとして固定(チームで揃える)
{
  "sdk": {
    "version": "8.0.402",
    "workloadVersion": "8.0.402"
  }
}

この固定化は「ダウンロード失敗を直接直す」ものではありませんが、毎回違うワークロードを引いてしまう状況を避け、調査と再現性を大幅に改善します。

再発防止:MAUI ビルドを安定させるパイプライン設計

ワークロードのインストールはネットワーク依存が強いので、「失敗しにくい構成」に寄せるのが最終的に一番早いです。現場でよく採用される打ち手を、安定度と運用コストで整理します。

方針安定度速度運用コスト向いているチーム
毎回 Microsoft-hosted で workload install△△(毎回DL)低まず動けば良い/小規模
Microsoft-hosted + パッケージ/ワークロードのキャッシュ○○中実行回数が多い/ビルド時間を縮めたい
Self-hosted にワークロードを事前導入(固定)◎◎中〜高安定最優先/社内ネットワーク前提
カスタムイメージ(VM/スケールセット)で標準化◎◎高複数プロジェクト/長期運用

キャッシュを使って「毎回の巨大ダウンロード」を減らす

Microsoft-hosted はジョブごとに VM が破棄されるため、何もしないと毎回ゼロからダウンロードになります。NuGet パッケージのキャッシュはパイプラインキャッシュで大きく改善できます。

例として、NuGet のグローバルパッケージフォルダを固定してキャッシュします。

variables:
  NUGET_PACKAGES: '$(Pipeline.Workspace)/.nuget/packages'

steps:

* task: Cache@2
  inputs:
  key: 'nuget | "$(Agent.OS)" | **/packages.lock.json'
  restoreKeys: |
  nuget | "$(Agent.OS)"
  path: '$(NUGET_PACKAGES)'

キャッシュキーに packages.lock.json を使う場合は、ロックファイルを生成する運用(依存関係の固定)もセットで考えると、再現性と速度が両立しやすくなります。

ワークロードのパック自体もキャッシュ対象にしたくなりますが、サイズが大きくなりがちです。まずは NuGet 側のキャッシュを整え、効果と容量のバランスを見て拡張していくのが現実的です。

リトライを「コマンド側」で持つ(外部要因に強くする)

外部配布元の一時不調やネットワーク瞬断が原因なら、同じ手順でも「次は通る」ことがあります。CI で毎回手動リランに頼らず、失敗したら数回だけ再試行するのは実務で効きます。

- powershell: |
    $ErrorActionPreference = "Stop"
    $max = 3
    for ($i = 1; $i -le $max; $i++) {
      try {
        dotnet workload install maui --verbosity detailed
        break
      } catch {
        if ($i -eq $max) { throw }
        Start-Sleep -Seconds (20 * $i)
      }
    }
  displayName: 'Install MAUI workloads with retry'

ポイントは「無限リトライ」にしないことと、「リトライの前にキャッシュを疑う(必要ならクリア)」を組み合わせることです。

フォーラム上の結論:Microsoft Q&A では Azure DevOps パイプラインはサポート対象外

今回の事象と同様の相談が Microsoft Q&A に投稿されたケースでは、受理された回答としてAzure DevOps(パイプライン)のトラブルは Q&A のサポート対象外であり、Developer Community(開発者コミュニティ)で相談するよう案内されています。つまり、そのスレッド内では技術的な解決策が提示されませんでした。

その一方で、実務としては次の 3 点を押さえるだけで、原因の当たりが付くことが多いです。

  • Microsoft-hosted / Self-hosted を切り分ける(環境要因かどうか)
  • --verbosity detailed で、どの URL/どのタイミングで落ちているかを特定する
  • サービス側の障害や不調がないか、Azure DevOps のステータス(インシデント)を確認する

Developer Community に相談する場合も、上記の情報が揃っているほど、回答が早く・正確になります。

まとめ:最短で直すチェックリスト

  1. 実行エージェント種別(Microsoft-hosted / Self-hosted)を確認する
  2. dotnet --version と dotnet workload --info をログに出し、「実際に使われている SDK」を確定する
  3. dotnet workload install maui --verbosity detailed で、落ちている取得先とタイミングを特定する
  4. Self-hosted なら dotnet nuget locals all --clear → dotnet workload repair を試す
  5. Microsoft-hosted なら VM イメージと SDK を固定し、必要ならキャッシュ/リトライを入れる
  6. 長期運用では、Self-hosted やカスタムイメージでワークロードを事前導入し、ネットワーク依存を最小化する

「YAML も SDK も変えていないのに突然壊れた」問題ほど、ログの粒度と切り分け順で解決までの時間が変わります。まずは詳細ログ化とエージェント種別の確定から始めてください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次