Safeguard
Developer Tools•

What is NuGet package pruning and does it cut audit false positives?

Package pruning removes packages the .NET runtime already provides from the restore graph, shrinking lock files and reducing NuGet Audit false positives.

Safeguard Security Team
4 min read

Package pruning drops packages from the restore graph when the .NET runtime already supplies them, such as an old System.Text.Json pulled in by a dependency. Fewer packages means fewer audit findings about code you never actually run. It is on by default for .NET 10 targets and opt in for .NET 9.

The problem

Libraries that support older frameworks often depend on packages that only matter for those frameworks. When your app targets a newer runtime, the platform already contains that functionality, and the assembly from the package is not used. Yet the package sits in your graph, and an audit with transitive checking can flag it.

Microsoft's PackageReference documentation uses System.Text.Json as the example: a project targeting .NET 9 or .NET 8 can still end up with an unneeded System.Text.Json 8.0.0 dependency.

How pruning works

Package kindWhat pruning does
Transitive, through another package or projectRemoved from the graph, not downloaded
Direct package referencePrivateAssets all and IncludeAssets none are applied
Direct reference that can be removed on .NET 10Warning NU1510 suggests deleting it
Project reference matching a pruned IDNot pruned, warning NU1511 on .NET 10

The SDK supplies the list of prunable packages based on the shared frameworks in your project. You can see a message at detailed verbosity when a package is pruned for a given framework.

Availability

  • Introduced with NuGet 6.13 and .NET SDK 9.0.200, first for transitive packages.
  • From the .NET 10 SDK, pruning affects direct packages too.
  • Opt in with the .NET 9 SDK using RestoreEnablePackagePruning set to true. Enabled by default for projects targeting .NET 10 or higher.
  • It needs the default dependency resolver released in NuGet 6.12.
<PropertyGroup>
  <RestoreEnablePackagePruning>true</RestoreEnablePackagePruning>
</PropertyGroup>

Effect on audit and lock files

Microsoft names two benefits: faster restores from smaller graphs, and fewer false positives from component scanners such as NuGet Audit. It is particularly useful with NuGetAuditMode set to all. Lock files change too. After enabling pruning on an existing project, the next lock file regeneration can show a larger than usual diff because pruned packages disappear.

A careful rollout

  1. Enable pruning in a branch and restore.
  2. Compare the audit warnings before and after, and record which packages vanished.
  3. Regenerate the lock file and review the diff.
  4. Run your tests, since pruning should not change runtime behavior, but verify.
  5. Treat any remaining finding on a pruned type of package as worth another look.

What pruning does not fix

It does not remove findings for packages you really use. A real vulnerable dependency stays in the graph. Pruning only trims what the runtime already covers.

Try it yourself

Click through it at your own pace, or open it full screen. See how removing findings that do not apply makes the remaining list easier to act on.

Safeguard's reachability analysis helps separate dependencies whose vulnerable code is used from those where it is not, and a free scan lets you try it.

Quick check

Is pruning on by default?

For projects targeting .NET 10 or higher with the .NET 10 SDK, yes. With the .NET 9 SDK it is opt in.

Will pruning hide a real vulnerability?

It removes only packages the runtime already provides. Packages you actually depend on stay in the graph.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.