.NET MAUI プロジェクトを久しぶりに開いたら、「dotnet workload restore が失敗」「NETSDK1147」「NETSDK1005」「MonoAOTCompiler.Task が見つからない」などのエラーが一気に出てビルド不能――そんな状況を体系的に整理し、「とりあえず今動かす」復旧手順と、将来を見据えた MAUI 9/10 への移行戦略までまとめて解説します。
.NET MAUI プロジェクトで「dotnet workload restore」が失敗する典型パターン
ここ数年の .NET / .NET MAUI / Visual Studio / Android SDK の進化は速く、プロジェクトを数か月〜1年放置すると「環境だけが勝手に進化してコードが置いて行かれる」状態になりがちです。 その結果、以下のようなエラーがまとめて発生します。
- NETSDK1147: 次のワークロードが必要: wasi-experimental
⇒ 「必要なワークロードがインストールされていない」ことを示す汎用エラーです。dotnet workload install <ID>で解決するのが基本ですが、ターゲット指定そのものが不要な場合もあります。 - MSB4236: SDK ‘Microsoft.NET.Runtime.MonoAOTCompiler.Task’ が見つからない
⇒ Android AOT コンパイル用の SDK/タスクが見つからない状態。MAUI / Android ワークロードが壊れているか、SDK 世代がズレています。 - NETSDK1005: Assets file ‘project.assets.json’ doesn’t have a target for ‘net8.0-windows10.0.19041.0’
⇒ NuGet が生成するproject.assets.jsonに、指定されたターゲット フレームワークの情報がない/壊れている状態です。 - NuGet パッケージ マネージャーの「インストール済み」が空になる
⇒ Visual Studio はproject.assets.jsonを前提に「インストール済み」一覧を構築するため、このファイルが壊れると UI 上は「何も入っていない」ように見えます。
さらに 2025 年時点では、.NET MAUI 8 は 2025/5/14 でサポート終了、サポート対象は .NET MAUI 9(~2026/5/12)と 10(~2027/5/11)のみ、という状況になっています。 Android SDK 35(Android 15)など新しい依存関係を組み合わせると、MAUI 8/9 と .NET SDK / Workload の“世代ズレ”が一気に噴出し、上記エラーを連鎖させます。
エラーごとに何が起きているのか
NETSDK1147: Missing workload for specified target
.NET SDK は「一部の機能をワークロードとして後付けインストールする」設計になっており、MAUI や Android / iOS / WASM などはすべてワークロードで提供されています。 NETSDK1147 は、
- プロジェクトが任意ワークロードを要求している
- しかしそのワークロードが
dotnetに見えていない
というときに出る汎用的なエラーです。
メッセージ例:
NETSDK1147: To build this project, the following workloads must be installed: wasi-experimental
To install these workloads, run the following command: dotnet workload install wasi-experimental
ポイントは「本当にそのワークロードが必要か?」を見極めることです。
- 本当に WASI/WASM をターゲットにしている →
dotnet workload install wasi-experimentalを実行 - MAUI プロジェクトに誤って WASI 設定を混ぜてしまった →
TargetFrameworksやRuntimeIdentifierから WASI 関連を取り除く
MSB4236: ‘Microsoft.NET.Runtime.MonoAOTCompiler.Task’ が見つからない
Microsoft.NET.Runtime.MonoAOTCompiler.Task は、Mono ベースの AOT コンパイル用タスクで、Android AOT ビルド時に使われます。 MAUI の Android ワークロードに含まれており、以下のようなときに見つからなくなります。
- MAUI / Android ワークロードがインストールされていない
- .NET SDK をアップデートしたが、ワークロードを再同期していない
- 複数バージョンの .NET SDK が混在し、古いワークロード マニフェストを参照している
そのため、後述の dotnet workload repair / install / update / restore を正しい SDK で実行し、MAUI / Android ワークロードを「入れ直す」ことが有効です。
NETSDK1005: project.assets.json にターゲットが無い
NETSDK1005 / NETSDK1047 は、NuGet が生成する project.assets.json に、指定したターゲット フレームワークの情報が欠けている場合に発生します。 典型的な原因は次の通りです。
<TargetFrameworks>に指定したフレームワーク(例:net8.0-windows10.0.19041.0)が restore 時に考慮されていない- 古いバージョンの MSBuild / NuGet を使って assets ファイルを生成してしまい、新しいフィールド(
TargetFrameworkAliasなど)が欠落している - ネットワーク エラーや社内 NuGet フィードの認証エラーで、復元が中途半端に失敗している
このため、obj フォルダーの削除 → NuGet キャッシュのクリア → 正しい SDK で再復元 という手順が非常に重要です。
NuGet「インストール済み」が空になる理由
Visual Studio の「インストール済み」タブは、プロジェクトごとの project.assets.json をもとに表示を作っています。
project.assets.jsonが生成されていない- 対象の
TargetFrameworkが assets の中に存在しない(=NETSDK1005状態)
という状況では、「実際には .csproj にパッケージ参照が書いてあるのに、インストール済みリストが空に見える」現象が起きます。復元を正常化すると、一覧も自然に復活します。
なぜ「去年はビルドできた」のに今はできないのか
根本的な理由は、「.NET MAUI / .NET SDK / Visual Studio / Android・iOS・Windows SDK がすべて別々のタイミングで更新される」からです。
- Windows Update や VS Installer が自動的に Visual Studio を更新
dotnetSDK を新しいバージョン(例: .NET 9 / 10)に手動で追加インストール- Android Studio や Android SDK Manager で最新 API をインストール
- しかしプロジェクト側の
TargetFrameworksや MAUI バージョンは古いまま
この「世代の食い違い」が一定ラインを超えると、ワークロードやビルド タスクの場所が変わり、前述のようなエラーになって表面化します。
.NET MAUI のサポート終了と Android 35 問題
2025 年現在の .NET MAUI サポート ポリシーは次の通りです。
| MAUI バージョン | 対応 .NET | サポート状態 | サポート終了日 |
|---|---|---|---|
| .NET MAUI 10 | .NET 10 | サポート中 | 2027-05-11 |
| .NET MAUI 9 | .NET 9 | サポート中 | 2026-05-12 |
| .NET MAUI 8 | .NET 8 | サポート終了 | 2025-05-14 |
一方、Android 側は Google Play Console の要件として 2025 年 8 月 31 日以降、API Level 35 以上をターゲットにすること が求められます。 ところが、.NET 8 の net8.0-android ワークロードは Android SDK 34 までしか対応しておらず、Android SDK 35 は .NET 9 / 10 側のワークロードでのみサポートされています。
つまり、
- MAUI 8(.NET 8)はそもそも 2025/5/14 でサポート終了
- さらに Android SDK 35 を使うこともできない
という二重の理由から、「MAUI 8 のまま新しい Android や OS に追従する」のは現実的ではありません。
とりあえず今のプロジェクトを .NET 8 のまま動かす復旧手順
長期的には MAUI 9/10 への移行が望ましいものの、「まずは今のコードをビルドできるようにしたい」というケースが多いはずです。 ここでは 既存の MAUI 8 プロジェクトを一旦動かす ことを目標にした手順を整理します。
ステップ 1: 現在の SDK / ワークロード状況を把握する
まずは CLI で、いまマシンに入っている SDK・ワークロードの一覧を確認します。
dotnet --info
dotnet --list-sdks
dotnet workload list
ここで注目したいのは次のポイントです。
- どのバージョンの .NET SDK が入っているか(例: 8.0.408 / 9.0.100 / 10.0.100 など)
- MAUI / Android / iOS / WASM 関連ワークロードが入っているか(
maui,maui-android,wasm-toolsなど)
特に、.NET 9 SDK 以降は Visual Studio / MSBuild 側にも最低バージョン要件があり、古い Visual Studio では .NET 9 SDK が正しく認識されません。
ステップ 2: global.json で「どの SDK を使うか」を固定する
ソリューション直下に global.json を置くと、そのフォルダー配下では dotnet が指定したバージョンの SDK を優先的に使うようになります。
例: プロジェクト作成当時に使っていた .NET 8 SDK が 8.0.408 の場合:
{
"sdk": {
"version": "8.0.408",
"rollForward": "disable"
}
}
これにより、
- マシン全体には .NET 9 / 10 SDK も入っている
- しかしこのソリューションだけは 8.0.408 を使う
という状態を強制できます。 SDK と MSBuild / Visual Studio のバージョン要件を満たしていれば、これだけで挙動が安定するケースも少なくありません。
ステップ 3: .csproj の TargetFrameworks を見直す
Windows を含む MAUI プロジェクトでは、TargetFrameworks に Windows プラットフォームを明示しないと、NETSDK1005 の原因になります。
典型例:
<PropertyGroup>
<TargetFrameworks>
net8.0-android;
net8.0-ios;
net8.0-maccatalyst;
net8.0-windows10.0.19041.0
</TargetFrameworks>
</PropertyGroup>
ポイント:
- Windows 向けは
net8.0-windows10.0.19041.0のように バージョン付き TFM を指定する - 実際にビルドしないプラットフォーム(例: iOS/macOS を Windows マシンでビルドしない)は、一旦外して原因切り分けするのも有効
NETSDK1005 が出ている場合は、
- 該当 TFM が
TargetFrameworksに含まれているか - 逆に csproj に書いた TFM が、新しい .NET SDK では非サポートになっていないか
を確認しましょう。
ステップ 4: 中間生成物と NuGet キャッシュをクリアしてから復元
壊れた project.assets.json が残っていると、どれだけ設定を直してもビルドが成功しないことがあります。 一度、ビルド成果物とキャッシュを全部捨ててから復元しましょう。
# ソリューション配下の bin/obj を削除
git clean -xfd # Git 管理外のファイルも消えるので注意
# NuGet ローカルキャッシュを削除
dotnet nuget locals all --clear
# もう一度パッケージ復元
dotnet restore
Git を使っていない場合は、エクスプローラーや PowerShell から bin / obj フォルダーを手動削除して構いません。
ステップ 5: MAUI / Android ワークロードを「整合させる」
ワークロード周りが怪しいときは、次の順番で CLI を実行するのがおすすめです。
# 1. 修復
dotnet workload repair
# 2. 一度アンインストールして入れ直したい場合
dotnet workload uninstall maui
dotnet workload install maui
# 3. プラットフォーム別に絞る場合
dotnet workload install maui-android maui-ios maui-maccatalyst maui-windows
# 4. SDK バージョンに合わせてマニフェスト更新
dotnet workload update
# 5. 最後にプロジェクト ルートで
dotnet workload restore
特に Microsoft.NET.Runtime.MonoAOTCompiler.Task のような Android AOT 関連のタスクは maui / maui-android ワークロードの一部として提供されているため、 MAUI / Android ワークロードの入れ直し が一番効きます。
ステップ 6: Visual Studio 側の構成も確認する
CLI だけ整えても、Visual Studio 側が古いままだと、.NET 9 SDK 以降が正常に認識されません。
- Visual Studio 2022 17.11 以前: .NET 9 SDK をインストールしても
net9.0がプロジェクトのターゲットに出てこない - Visual Studio 2022 17.12 以降: .NET 9 フルサポート(執筆時点の最新は 17.14)
VS Installer で以下を確認しましょう。
- ワークロード「.NET マルチプラットフォーム アプリ UI 開発」がインストールされているか
- .NET SDK 9 / 10 の個別コンポーネントが入っているか
CLI だけで開発している場合でも、MSBuild バージョンとの整合性という意味で、最低限の Visual Studio または Build Tools を最新版にしておくと安定します。
よく使うコマンドと役割まとめ
| コマンド | 役割 | いつ使うか |
|---|---|---|
dotnet --info | インストール済み SDK・ランタイムを一覧表示 | 環境の「世代」を把握したいとき |
dotnet --list-sdks | SDK バージョン一覧を表示 | global.json で固定するバージョンを選ぶとき |
dotnet workload list | インストール済みワークロードを表示 | MAUI / Android ワークロードの有無を確認したいとき |
dotnet workload repair | 破損したワークロードの修復 | アップデート後にビルドが急に失敗し始めたとき |
dotnet workload install | 指定ワークロードの新規インストール | エラー メッセージで「このワークロードが必要」と出たとき |
dotnet workload update | 現在の SDK 用にワークロードを更新 | SDK をアップデートしたタイミング |
dotnet workload restore | プロジェクトに必要なワークロードを復元 | リポジトリをクローンした直後など |
長期的には MAUI 9 / 10 への移行が必要
ここまでの手順で「とりあえず .NET 8 のままビルドできる」状態には持っていけますが、前述の通り MAUI 8 自体がサポート終了済み であり、Android 35 を含む最新 OS 事情に追随するには、少なくとも MAUI 9 以上が必須になりつつあります。
実務的には、
- 既存プロジェクトを直接アップグレードするより
- MAUI 9 / 10 の新規テンプレートを作り、そこにコードを移植する
方が、結果的に早く、かつ「古い設定を引きずらない」のでおすすめです。
MAUI 9 / 10 への移行フロー(ざっくり)
- Visual Studio を更新
.NET 9 / 10 をフルに扱うには、Visual Studio 2022 17.12 以降が推奨です。 - 新規に MAUI 9 / 10 プロジェクトを作成
- GUI: 「.NET MAUI アプリ」テンプレートで新規作成
- CLI:
dotnet new maui -n MyNextMauiApp
- アプリ構造だけを新テンプレートに合わせる
App.xaml,AppShell.xaml,MainPage.xamlなどを比較- 古いプロジェクトの View / ViewModel / Service クラスを段階的にコピー
- NuGet パッケージを整理し、最新版で揃える
Central Package Management(Directory.Packages.props)を使っている場合は、そちらでバージョンを整えます。 - ターゲット フレームワーク / Android API レベルを既定値に寄せる
新テンプレートが提案するTargetFrameworksと Android 設定を尊重し、むやみに上げすぎないようにします(API 35 が必要なら MAUI 9/10 を選ぶ)。 - 各プラットフォームごとにビルド確認
最初は Android / Windows のように 1 つずつ増やしていき、「どのプラットフォームで詰まっているか」を切り分けます。
MAUI 9/10 プロジェクトの csproj 例
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>
net9.0-android;
net9.0-ios;
net9.0-maccatalyst;
net9.0-windows10.0.19041.0
</TargetFrameworks>
<OutputType>Exe</OutputType>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="<最新版>" />
<!-- 他のパッケージ -->
</ItemGroup>
</Project>
古い MAUI 8 プロジェクトとの違いが大きい場合は、差分を一気に埋めようとせず、「アプリの壊れにくい層から移植する」(ViewModel → Service → View の順など)とスムーズです。
トラブルパターン別のチェックリスト
ここからは、よくある「沼ポイント」をパターン別にチェックリスト形式でまとめます。
パターン A: dotnet workload restore を何度打っても NETSDK1147 が消えない
- エラーメッセージに表示されているワークロード ID をメモ(例:
wasi-experimental,maui-androidなど) dotnet workload listで、その ID が本当に未インストールか確認- 未インストールなら
dotnet workload install <ID>を実行 - それでも直らない場合は、global.json で SDK を固定した上で
dotnet workload repairを実行 - WASI を使うつもりがないのに
wasi-experimentalを要求される場合は、TargetFrameworks/RuntimeIdentifierに WASI 由来のターゲットが紛れ込んでいないか確認
パターン B: project.assets.json まわりのエラー(NETSDK1005)
objフォルダーを削除してから再ビルドしたか?- CSProj の
TargetFrameworksに、エラーメッセージに出ている TFM が含まれているか? - 企業内 NuGet フィードなど、認証が必要なフィードへの接続が切れていないか?(ここで失敗すると assets が中途半端に生成されます)
- ローカルの NuGet クライアント / MSBuild バージョンが古くないか?(VS 2022 + 最新 SDK が基本)
パターン C: Android だけビルドが通らない(MonoAOTCompiler.Task 系)
dotnet workload listにmaui,maui-android,androidが含まれているか?dotnet workload repair/dotnet workload install maui-androidを実行したか?- Android SDK Manager で、API Level 33/34/35 をごちゃ混ぜにインストールしていないか?(MAUI 8 は 35 非対応)
- いったん
<AndroidUseLatestPlatformSdk>true</AndroidUseLatestPlatformSdk>を外し、テンプレート既定値に寄せてみる
パターン D: Visual Studio の UI と CLI の挙動が食い違う
- Visual Studio 2022 のバージョンは 17.12 以降か?(古いと .NET 9 SDK が正しく扱えない)
global.jsonで指定している SDK が、VS 側ではインストールされていない、ということはないか?- VS を再起動しても現象が続くか?(workload repair 後は再起動が必要になることがあります)
運用を安定させるためのおすすめルール
最後に、「同じ問題で何度も時間を溶かさない」ための運用ルールをいくつか提案します。
ルール 1: すべてのリポジトリに global.json を置く
- プロジェクト作成時点の SDK バージョンを
global.jsonに固定してコミット - 後で SDK を上げる場合も「PR を切って明示的に上げる」運用にする
- CI でも同じ
global.jsonを利用し、「ローカルは動くが CI だけ落ちる」を防止
ルール 2: 「このプロジェクトはどの MAUI バージョン想定か」を README に書いておく
- README に「このプロジェクトは .NET 8 / .NET MAUI 8 で作られました」と明記
- MAUI 9 / 10 へ移行したタイミングで、README と
global.jsonを一緒に更新 - サポート終了日(例: MAUI 8 → 2025/5/14)も書いておくと、移行タスクの優先度付けがしやすくなります
ルール 3: メジャー バージョンをまたぐときは「新規テンプレートに移植」が基本
- MAUI 8 → 9 / 10 など、大きいバージョンアップは「新プロジェクトを作って移植」が安全
- csproj や
Directory.Packages.propsを無理に手作業で書き換えるより、最新テンプレートを基準に差分を吸収する方がトラブルが少ない
ルール 4: OS / SDK 側の制約を早めに把握する
- Android の API Level 要件(Google Play Console)
- iOS / Xcode のサポート範囲
- Windows のターゲット バージョン(10.0.19041 など)
このあたりは .NET / MAUI のサポート ポリシーと切り離されているため、「Android だけ無理に新しくした結果、MAUI 側が追いつかずビルド不能」になりがちです。
まとめ
.NET MAUI プロジェクトで dotnet workload restore が失敗し、NETSDK1147 / MSB4236 / NETSDK1005 などのエラーが雪崩のように出るとき、多くの場合は 「SDK / ワークロード / Visual Studio / ターゲット OS の世代ズレ」 が原因です。
本記事で紹介したように、
global.jsonで SDK を固定する- csproj の
TargetFrameworksを整理する - 壊れた
project.assets.jsonと NuGet キャッシュをクリアして再復元する - MAUI / Android ワークロードを
workload repair / install / update / restoreで同期し直す
といった手順を踏めば、「とりあえず今動かす」ところまではたいてい復旧できます。
しかし、MAUI 8 は既にサポート終了となっており、Android 35 など最新 OS に対応するには MAUI 9 / 10 への移行が避けられません。 早めに新しいテンプレート プロジェクトを立ち上げ、段階的にコードを移植していくことで、「ある日突然ビルド不能になる」リスクを減らしつつ、モダンな .NET の恩恵も享受できるようになります。
いま手元でビルドできているとしても、「サポート ポリシーと OS 要件をカレンダーに書き込む」 ところから、ぜひ一度見直してみてください。

コメント