Skip to content

MS_NuGetHigherVersion

nishi_74322014 edited this page Sep 1, 2026 · 1 revision

Nuget使用時に「which has a higher version X than the version Y in the current target framework...」が発生

概要

  • NuGet は非常に便利だが、この問題がよく起きるようになった。

  • 以下のようなメッセージが表示される。

    • プライマリ参照 XXXX は、現在のターゲット フレームワークのバージョン "n.n.n.n" より
      高いバージョン "n.n.n.n" を持つ YYYYY に間接的に依存するため、解決できませんでした。

    • The primary reference "XXXX", Version n.n.n.n, .....could not be resolved
      because it has an indirect dependency on the "YYYYY", Version n.n.n.n, .....
      which has a higher version "n.n.n.n" than the version n.n.n.n in the current target framework.

補足(エラー番号): このメッセージは MSB3268 に対応する。
MSB3247 が「競合を検出した」という警告であるのに対し、
こちらは参照を解決できなかったというエラーである点が異なる。

【MSB3247(警告)】  版が食い違うが、とりあえず bin には置ける
【MSB3268(エラー)】 ターゲット フレームワークが提供する版より
                       NuGet が持ってきた版の方が新しく、解決できない

つまり本エラーは、
「NuGet パッケージ版のアセンブリ」と
「ターゲット フレームワーク(BCL)に組み込みのアセンブリ」が
同じ名前で競合している
という、特殊な形の衝突である。

詳細

原因

  • この問題は、NuGet パッケージのバージョンアップ作業などで、
    BCL と異なるフレームワーク バージョンで動き始めた場合に発覚したりする。

  • netcoreappではなく、
    バインディング リダイレクトがある net であっても、
    ピンポイントに特定バージョンの NuGet パッケージをインストールする
    必要があるケースもある。

補足(典型例は System.Net.Http: 原文が挙げている
System.Net.Http は、まさにこの問題の代表例である。

.NET Framework 4.x  ─┬─ BCL に System.Net.Http 4.0.0.0 が組み込み
                     │
NuGet                └─ System.Net.Http 4.3.x(アセンブリ版 4.1.1.x 等)

  → 同じ名前・同じ公開鍵トークンで、版だけが違うアセンブリが 2 つ存在する
  → どちらを使うべきか解決できない

System.* 系の NuGet パッケージは、
「新しい API を古いフレームワークでも使えるようにする」ために
BCL と同名のアセンブリを配るという設計だったため、
この衝突が構造的に起きやすかった。

同種の問題を起こしやすいものを挙げておく。

パッケージ 備考
System.Net.Http 最も有名。Web API クライアントで頻発
System.Runtime / System.Threading.Tasks 旧「契約アセンブリ」群
System.ValueTuple 4.6.2 以前で必要
System.Buffers / System.Memory Span 系
NETStandard.Library CS0012 とも関係

対応

対応の一例として以下のような手順で解消したことがある。

  • System.Net の NuGet パッケージを BCL のアセンブリに変更し、
  • 再構成(Microsoft.AspNet.WebApi.Client を再インストール)

補足(現在の対処/最新化): 原文の対処
NuGet 版をやめて BCL 版に戻す)は現在も有効で、
むしろこれが第一候補である。

① BCL に組み込まれているなら、NuGet 版を外す

ターゲットが net472 以降なら、System.Net.Http は BCL にある
  → NuGet の System.Net.Http パッケージをアンインストール
  → 参照設定でフレームワークの System.Net.Http を参照

② ターゲット フレームワークを上げる

net45 のまま新しいパッケージを使おうとすると衝突しやすい。
net472 以降に上げると、多くの System.* パッケージが不要になる
.NETバージョンアップ)。

③ どうしても NuGet 版が必要なら、バインディング リダイレクトを書く

<dependentAssembly>
  <assemblyIdentity name="System.Net.Http"
                    publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.0.0.0" />
</dependentAssembly>

newVersion を BCL 側(4.0.0.0)に向けるのがコツで、
通常のリダイレクト(新しい方に寄せる)とは逆向きになる。
ここが混乱しやすい点である。

④ .NET Core / .NET に移行する

System.* の分割パッケージ問題自体が存在しない
(すべてランタイムに含まれる)ため、根本的に解消する
.NET Coreへの移行)。

対処 効果 手間
① NuGet 版を外す 根本解決(衝突源が消える)
② ターゲットを上げる 根本解決
③ バインディング リダイレクト 対症療法
④ .NET へ移行 構造的解決

補足(調査の手順): どこから「高いバージョン」が来ているかは、
ビルド ログの ResolveAssemblyReferences を見れば分かる
MSB3247 の「ビルド出力の詳細化」と同じ手順)。

msbuild Foo.sln -v:d -bl:build.binlog
# ResolveAssemblyReferences の
#   「Primary reference」「Dependency」「Resolved file path」を追う
# 誰がそのパッケージを引き込んでいるかを見る
dotnet list package --include-transitive

参考

Microsoft Learn


Tags: 移行, .NET開発, デプロイ, デバッグ, NuGet

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally