391043 Stack
📖 Tutorial

How NuGet Package Pruning Reduces False Vulnerability Alerts in .NET 10

Last updated: 2026-05-19 16:17:26 Intermediate
Complete guide
Follow along with this comprehensive guide

In .NET 10, a new feature called package pruning addresses a common frustration: false-positive vulnerability warnings from transitive dependencies that are already covered by the runtime. This Q&A explains how it works, why it matters, and what changes developers can expect.

What is NuGet package pruning and how does it work in .NET 10?

Package pruning is a NuGet feature in .NET 10 that automatically removes platform-provided packages from the dependency graph during restore. When you build a .NET project, NuGet resolves all direct and transitive dependencies. If a package—like System.Text.Json—is already supplied by the .NET Runtime Libraries, NuGet can exclude it from the resolved graph. The .NET SDK maintains a list of packages and their highest version for each target framework. If a transitive dependency falls within that version range, NuGet prunes it. This means your project no longer downloads or references those redundant packages, leading to a cleaner restore process and fewer false alerts.

How NuGet Package Pruning Reduces False Vulnerability Alerts in .NET 10
Source: devblogs.microsoft.com

Why do transitive dependency vulnerability warnings often turn out to be false positives?

Many libraries on nuget.org still target netstandard2.0 and carry dependencies on packages like System.Memory or System.Text.Json—packages that are now part of the .NET Runtime Libraries. While your app uses the runtime’s built-in version, NuGet resolves the older transitive package. When a CVE is published against that older version, vulnerability scanners flag it, even though your app never actually runs that code. This creates a false positive: the warning exists in the dependency graph but has no real security impact. Package pruning eliminates these phantom warnings by removing the outdated transitive package from the graph entirely.

How does package pruning reduce the number of vulnerability reports by 70%?

Microsoft’s telemetry shows that projects using the .NET 10 defaults—where NuGet audits all transitive dependencies and package pruning is enabled—see 70% fewer transitive vulnerability reports compared to previous defaults. This dramatic drop happens because pruning removes the root cause of many false positives: platform-provided packages that are already safe. Without pruning, a single library pulling in an outdated System.IO.Pipelines could trigger several CVEs. After pruning, that package is gone from the graph, so NuGet Audit no longer reports it. The remaining warnings are far more likely to be genuine, making it easier for developers to prioritize and fix real vulnerabilities.

What causes transitive packages to remain in the dependency graph even when the runtime provides them?

Two main factors keep these packages in the graph. First, many NuGet packages—especially older ones—were built for maximum compatibility using netstandard2.0. They explicitly list dependencies that later became part of the .NET runtime. Second, the platform evolves: packages like System.Text.Encodings.Web or System.IO.Pipelines began as standalone NuGet packages and were later absorbed into the runtime. When your project references a library that still declares those old dependencies, NuGet resolves them even though the runtime provides a newer version. The package exists on nuget.org, NuGet fetches it, and vulnerability scanners flag it—even though your app uses the runtime’s built-in implementation. Package pruning breaks this cycle by removing those irrelevant entries.

How NuGet Package Pruning Reduces False Vulnerability Alerts in .NET 10
Source: devblogs.microsoft.com

How does the .NET SDK determine which packages can be pruned?

The .NET SDK includes a built-in mapping for each target framework—for example, net8.0, net9.0, and net10.0. This mapping lists every package that the runtime supplies along with the highest version it provides. During restore, NuGet checks each transitive dependency against this list. If the package name matches and the version in the graph is equal to or lower than the provided version, NuGet prunes it. For instance, if your project targets net8.0, the SDK knows it includes System.Text.Json 8.0.x. A transitive dependency on System.Text.Json 8.0.0 would be pruned, but one on version 9.0.0 would not—because 9.0.0 is higher than what the runtime supplies. This version-aware logic ensures pruning only removes truly redundant packages.

What are the benefits of cleaner dependency graphs beyond fewer vulnerability warnings?

Beyond reducing false positives, package pruning delivers several practical advantages:

  • Smaller restore graphs: Fewer packages to resolve means less download time and fewer entries in the graph.
  • Reduced noise: Developers spend less time investigating warnings that have no real impact.
  • Clarity on actual dependencies: Pruning removes stale references, making it clear that your app does not rely on outdated packages separately.
  • Faster builds: With fewer packages to restore and analyze, the restore step completes more quickly.

Overall, pruning simplifies the dependency tree and lets developers focus on packages that truly need attention.

How does package pruning handle cases where the transitive dependency version exceeds the runtime-provided version?

If a transitive dependency requests a version higher than what the runtime provides, NuGet does not prune it. For example, when targeting net8.0, the runtime supplies System.Text.Json up to version 8.0.x. A transitive dependency on version 9.0.0 means your app would actually need that newer package, so it stays in the graph. This design ensures that pruning only removes packages that are truly redundant. If a newer version is required, NuGet respects the dependency and restores it. This version-aware logic prevents accidental removal of packages that provide features not yet available in the runtime, keeping your application functional while still cleaning up false positives.