Transitive pinning is a central package management setting that lets you override the version of an indirect dependency without adding a direct reference in every project. Turn on CentralPackageTransitivePinningEnabled, list the safe version in Directory.Packages.props, and NuGet promotes it for you.
Why it exists
When a transitive package has an advisory and its parent has not updated, the usual fix is to add a direct PackageReference to a fixed version. In a solution with dozens of projects, that becomes dozens of edits that someone must remember to remove later. Transitive pinning moves the decision to one file.
How to turn it on
Start with central package management: a Directory.Packages.props at the repository root with ManagePackageVersionsCentrally set to true. Then add the pinning property and a PackageVersion entry for the package you want to force.
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
If a project references PackageA, which depends on PackageB 1.0.0, restore will use PackageB 2.0.0 instead. No project file mentions PackageB.
Rules and limits
| Behavior | What happens |
|---|---|
| Pin higher than requested | Works, the higher version is used |
| Pin lower than requested | Not allowed, restore raises NU1109 |
| Property location | A project, Directory.Packages.props, or Directory.Build.props |
| Packing your project | Pinned packages become explicit dependencies in the nuspec |
The last row deserves attention. If you publish a library from the same repository, pinning can add dependencies your consumers did not have before, even though your code never calls that package. Microsoft advises weighing this when authoring libraries.
A cleanup routine
Pins are meant to be temporary. Keep them honest.
- Add a comment beside each pin with the advisory link and the date.
- Review pins when the parent package updates.
- Remove the pin when the parent's own range already excludes the bad version.
- Re-run restore with audit on to confirm nothing regressed.
- Keep the lock file in step so the fix is visible in a diff.
Where it fits in a fix ladder
Microsoft's own guidance for a vulnerable transitive package is to try, in order: update the top-level package, update the package closest to your direct references, add the fixed version as a direct reference, or use central package management with transitive pinning. Pinning is a good fit when many projects share the problem.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how a fixed version is proposed alongside the finding.
Safeguard can open fix pull requests for dependency upgrades when you enable autonomous remediation, which is off by default, and a free scan shows what is fixable.
Quick check
Can I pin a transitive package to an older version?
No. Pinning lower than a dependency requests raises NU1109.
Does transitive pinning change what my NuGet package depends on?
Yes. When you pack, pinned packages are promoted to explicit dependencies, so review it before publishing a library.
Sources
- Central Package Management, Microsoft Learn
- Auditing package dependencies for security vulnerabilities, Microsoft Learn
Last reviewed: 19 October 2026.