MS_NuGetNU1605 - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

dotnetコマンドのビルドで「error NU1605 Detected package downgrade」が発生

概要

Linux 上の .NET Core 環境で dotnet コマンドのビルドで
「error NU1605: Detected package downgrade」が発生した。

補足(エラーの意味): NU1605 は
「依存関係の解決の結果、要求されている版より古い版が選ばれた」
という状態を指す。

あなたのプロジェクト
  ├─ 直接参照:  Foo 1.0.0
  └─ LibA 2.0 ──> Foo 2.0.0 を要求

  → NuGet は「直接参照を優先」する規則があるため Foo 1.0.0 を選ぶ
  → LibA が要求する 2.0.0 より古い = ダウングレード
  → NU1605

重要な性質: NuGet は
「最も高い最小バージョン」を選ぶのが原則だが、
直接参照(PackageReference)だけは例外的に最優先される。
このため、直接参照の版を古いまま放置していると、
推移的依存が新しくなった時点で NU1605 になる。

実行時に FileLoadException / MissingMethodException
起こす可能性があるため、警告ではなくエラーとして扱われる。

詳細

  • publish や restore で内部で NuGet を使用する際に
    発生する模様(なので ErrId も NU から始まっている)。

  • 以下で治る(詳細不明、必要に応じて追記)。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <NoWarn>$(NoWarn);NU1605</NoWarn>
  </PropertyGroup>
</Project>

移行メモ(この対処は「治る」ではなく「黙らせる」): 原文が
「詳細不明」としている通り、NoWarn
エラーを抑止しているだけで、問題は残る

NoWarn で NU1605 を消す
  → ビルドは通る
  → しかし古い版が使われる状態は変わらない
  → 実行時に MissingMethodException 等で落ちる可能性が残る

本来の対処は、直接参照の版を引き上げることである。

<!-- 推移的依存が要求する版以上に、直接参照を引き上げる -->
<PackageReference Include="Foo" Version="2.0.0" />

手順:

# ① 誰が何を要求しているかを可視化する
dotnet list package --include-transitive

# ② エラー メッセージ自体に経路が書かれている
#    「Foo 1.0.0 -> Bar 2.0.0」という形で依存の連鎖が示される

# ③ 直接参照の版を上げる
dotnet add package Foo --version 2.0.0

NoWarn が妥当な場面は限られる。

場面 妥当か
版を上げると別のパッケージが壊れる(一時回避) (期限を切って対応)
古い版で問題ないと検証済み
原因を調べずに黙らせる ×

抑止するなら、対象を限定する方が安全である。

<!-- そのパッケージだけ抑止する -->
<PackageReference Include="Foo" Version="1.0.0" NoWarn="NU1605" />

補足(TreatWarningsAsErrors との関係): NU1605 は
NuGet 側の設定で、警告にもエラーにもできる

<PropertyGroup>
  <!-- NU1605 を警告に格下げする(既定はエラー) -->
  <WarningsNotAsErrors>$(WarningsNotAsErrors);NU1605</WarningsNotAsErrors>
</PropertyGroup>

歴史的には、

時期 扱い
.NET Core 1.x 警告(NU1605 は warning)
.NET Core 2.0 以降 エラーに格上げ

という変更があり、原文が参照している
NuGet/Home Issue #5594 はまさにこの変更に関する議論である。
**「2.0 に上げたら急にビルドが通らなくなった」**という
当時の混乱が背景にある。

補足(プロジェクト参照でも起きる): NU1605 は
パッケージ間だけでなく、プロジェクト参照が絡んだ場合にも起きる。

App.csproj  ──> Newtonsoft.Json 12.0.0(直接参照)
           └──> Lib.csproj ──> Newtonsoft.Json 13.0.3

  → App 側が古い → NU1605

対処: 上位(App)側の版を、下位(Lib)以上に揃える
リポジトリ全体で版を統一したい場合は、
中央パッケージ管理Directory.Packages.props)が有効である
NuGetでインストールすると依存関係が増えすぎる問題 の補足を参照)。

なお、Directory.Packages.props を使っていても
VersionOverride で個別に下げると NU1605 になる
ため、
例外を作る際は注意する。

参考

Microsoft Learn


Tags: 移行, テスト, デバッグ, デプロイ, .NET開発, .NET Core

⚠️ **GitHub.com Fallback** ⚠️