Buconos

Understanding NuGet Package Pruning in .NET 10: Reducing Dependency Noise and False Vulnerability Alerts

Published: 2026-05-20 18:48:09 | Category: Cybersecurity

If you've ever run a NuGet audit or a vulnerability scanner on a .NET project, you've likely encountered warnings for transitive packages that you never explicitly installed. These warnings often point to packages like System.Text.Json or System.Text.Encodings.Web—packages that are now provided at a newer version by the .NET Runtime Libraries. In many cases, the vulnerability warning is a false positive. In .NET 10, NuGet introduces a feature called package pruning, which automatically removes such redundant packages from the restore graph, leading to cleaner dependencies and more actionable vulnerability reports.

Background: The Problem of Transitive Dependencies

Many libraries on nuget.org target netstandard2.0 for maximum compatibility, and they still carry dependencies on packages like System.Memory and System.Text.Json—packages that are now part of the .NET Runtime Libraries. This isn't limited to older packages; as the platform evolves, packages that once shipped independently become part of the runtime. For instance, System.IO.Pipelines started as a standalone NuGet package and later became integrated into the platform.

Understanding NuGet Package Pruning in .NET 10: Reducing Dependency Noise and False Vulnerability Alerts
Source: devblogs.microsoft.com

Consider a .NET 10 project that depends on such a library. That library may pull in System.Text.Json 8.0.0 as a transitive dependency, even though the .NET 10 runtime already ships a newer version. The package on nuget.org still exists, NuGet still resolves it, and when a CVE is published against it, vulnerability scanners still flag it—despite the fact that your application uses the runtime-provided version.

Core Issues

  • False-positive vulnerability warnings: When a CVE is published against a platform-provided package, NuGet Audit reports it as a transitive vulnerability, even though the .NET Runtime Libraries already provide a patched version. The package appears in the graph, but it's not what your app actually uses.
  • Larger restore graphs: More packages to resolve means more downloads, more graph entries, and more noise during build and restore operations.
  • Stale package references: Older and unsupported package entries remain in the graph even when your app is actually using the in-box .NET Runtime Libraries implementation. Pruning removes these redundant references, making it clearer that your app no longer depends on an outdated package separately.

What Is Package Pruning?

Package pruning is a process that removes platform-provided packages from the NuGet dependency graph at restore time. If a package is already supplied by the .NET Runtime Libraries, NuGet can exclude it from the resolved graph entirely. The .NET SDK maintains a list of packages that are provided by each target framework, along with the highest version that framework supplies. If a transitive dependency falls within that version range, NuGet prunes it.

For example, net8.0 includes System.Text.Json version 8.0.x, so a transitive dependency on System.Text.Json 9.0.0 is not pruned when targeting net8.0. However, a dependency on System.Text.Json 8.0.0 would be pruned because the runtime already provides that version or higher.

Understanding NuGet Package Pruning in .NET 10: Reducing Dependency Noise and False Vulnerability Alerts
Source: devblogs.microsoft.com

How Pruning Works During Restore

During a NuGet restore, the SDK compares each transitive package against the list of platform-provided packages. If a match is found and the version is within the range supplied by the target framework, the package is excluded from the final restore graph. This reduces the number of packages that need to be downloaded and resolved, and more importantly, eliminates the false vulnerability warnings that previously cluttered reports.

Benefits of Package Pruning

The introduction of package pruning brings several concrete improvements to .NET projects:

  • 70% fewer transitive vulnerability reports: According to telemetry from Microsoft, projects using the new default settings (with NuGetAuditMode set to all) see a 70% reduction in transitive vulnerability warnings compared to projects using previous defaults.
  • Cleaner dependency graphs: Pruning removes stale and redundant package references, making it easier to understand what your project actually depends on.
  • Faster restore times: With fewer packages to resolve, NuGet restore operations become faster and more efficient.
  • More actionable vulnerability reports: Since false positives are eliminated, developers can focus on real vulnerabilities that need attention.

Conclusion

NuGet package pruning in .NET 10 is a welcome improvement for .NET developers managing dependencies. By automatically removing platform-provided packages from the restore graph, it reduces noise, eliminates false vulnerability warnings, and streamlines the development workflow. Whether you're maintaining a large enterprise project or a small library, this feature helps ensure that your dependency tree reflects what you're actually using—not what legacy transitive packages might suggest. As the .NET platform continues to evolve, such optimizations make the development experience smoother and more reliable.