deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

.NET 10 NU1510 package pruning can fail CI restores; the fix depends on your target frameworks

.NET 10 enables NuGet package pruning by default, and the NU1510 diagnostic can fail CI restores when warnings are treated as errors. The safe fix differs between net10.0 apps and multi-target libraries.

.NET 10 NU1510 package pruning can fail CI restores; the fix depends on your target frameworks

Upgrading to the .NET 10 SDK can turn a routine restore into a CI failure, because NuGet package pruning is now enabled by default for projects targeting .NET 10 or later. A write-up on dev.to explains why the NU1510 diagnostic appears, why deleting the flagged package reference everywhere is the wrong reflex, and how to fix the issue per target framework.

How NU1510 becomes a CI failure

According to the dev.to article, NuGet raises NU1510 when a direct reference to a package registered for pruning can be removed entirely, because the targeted SDK already supplies the same or a higher assembly version. The diagnostic is deliberately narrow: it is not a general-purpose unused-package detector and does not apply to arbitrary third-party packages.

The failure surfaces in CI because many repositories set TreatWarningsAsErrors globally. The article's example adds a direct reference to System.Text.Json 10.0.11 in a net10.0 project; with the stable .NET SDK 10.0.303, restore exits with code 1 because NU1510 has been promoted from a warning to an error. Without a warnings-as-errors policy, the same condition normally produces only a warning.

The article notes that Microsoft's .NET 10 breaking-change guidance recommends removing the reference when every target can prune it, or conditioning the reference when an older target still needs it.

The right fix depends on the target

For a net10.0-only application, the fix is simply to delete the PackageReference. The framework still supplies System.Text.Json, and the sample application continues to import it and serialize the same payload after the reference is removed.

A multi-target library needs a different answer. The sample supports both netstandard2.0 and net10.0, so removing the reference globally would strip a dependency the older target requires. The fix is to make the requirement explicit in MSBuild by conditioning the PackageReference so it applies only when the target framework is netstandard2.0.

NuGet restore builds a separate dependency graph for each target framework, and dotnet pack produces framework-specific dependency metadata. The author points out that an unconditioned reference still needed by one target does not produce NU1510, because it cannot be removed from every target; the explicit condition exists to make the intent reviewable. Current pack behavior omits a prunable dependency from the net10.0 group while retaining it for the older target. For a larger framework matrix, a compatibility-based condition may be easier to maintain, but it still needs verification against every supported target.

Verify the dependency graph, not just the warning

A disappearing warning is not treated as sufficient evidence in the article. The author builds a verifier that checks nine behaviors: the broken restore fails with NU1510, the diagnostic names System.Text.Json, the fixed application runs, its build assets contain no package copy, and the multi-target assets plus the packed nuspec keep the dependency only for netstandard2.0. The verifier reports PASS 9/9, and five repeated runs produced byte-identical output.

The article is also explicit about a limitation: the sample executes the modern application, while the older library target is validated through restore, build, assets metadata and the packed nuspec. It does not claim to execute a netstandard2.0 application.

When not to remove a reference

The approach applies only when the SDK or a referenced framework has registered a package for pruning. A custom package is not made redundant merely because its namespace resembles framework functionality. The sample covers only the SDK-provided System.Text.Json case; it does not model the separate FrameworkReference and transitive ProjectReference scenario described in the diagnostic documentation, and it makes no claims about restore size or speed.

Before removing a reference in a real library, the author recommends restoring, building, testing and packing every supported target, then inspecting the resulting dependency groups, especially when central package management or more complex MSBuild conditions are involved. Suppressing NU1510 may unblock a migration temporarily, but it does not establish whether the published dependency contract is correct.

Why it matters

Warnings promoted to errors are among the most common ways SDK upgrades break CI pipelines, and the tempting fix, deleting the flagged reference everywhere, silently breaks consumers of a library that still targets netstandard2.0. Treating NU1510 as a per-target dependency decision keeps restores green while preserving compatibility for older runtimes, and verifying the packed output closes the gap between the warning being gone and the published package actually being correct.

  • #dotnet
  • #nuget
  • #ci-cd
  • #package-management
  • #msbuild

Related posts