Safeguard
Developer Tools•

How do I make a .NET build fail on vulnerable NuGet packages?

Treat NuGet audit warnings NU1901 to NU1904 as errors, ideally in a dedicated audit pipeline, so new advisories do not block unrelated fixes.

Safeguard Security Team
4 min read

NuGet audit runs during restore and raises warnings NU1901 to NU1904 by severity. To fail a build, treat those warning codes as errors. Many teams do this in a dedicated audit pipeline, so a newly published advisory does not block an urgent unrelated fix on developer machines.

Definitions

NuGet Audit. The restore time check of your packages against vulnerability data from your configured audit sources.

Warning code. NU1901 is low severity, NU1902 moderate, NU1903 high and NU1904 critical, per Microsoft documentation.

Audit source. A package source that provides vulnerability information.

Settings that matter

PropertyDefaultMeaning
NuGetAudittrueTurns auditing on or off
NuGetAuditLevellowMinimum severity to report
NuGetAuditModedirect, or all for net10.0 and higherWhether transitive packages are audited

The mode default matters. For projects before .NET 10, transitive packages are not audited unless you set the mode to all.

Steps

  1. Set the audit mode to all so transitive packages are checked.
  2. Pick a severity floor, for example moderate.
  3. Decide where failure belongs. A per commit pipeline gives fast feedback but can break on a Friday advisory. A dedicated audit pipeline gives a steady signal without that risk.
  4. Configure the warning codes as errors under the right condition.
  5. Keep local builds as warnings, so developers see issues without being blocked.
<PropertyGroup>
  <NuGetAuditMode>all</NuGetAuditMode>
  <NuGetAuditCodes>NU1901;NU1902;NU1903;NU1904</NuGetAuditCodes>
  <WarningsAsErrors Condition=" '$(AuditPipeline)' == 'true' ">$(WarningsAsErrors);$(NuGetAuditCodes)</WarningsAsErrors>
</PropertyGroup>

Then restore with the AuditPipeline property set to true in that pipeline alone.

Tradeoffs

ChoiceBenefitCost
Errors everywhereNothing ships with known issuesNew advisories can block releases
Errors in an audit pipelineSteady signal, no surprise blocksNeeds someone to watch the pipeline
Warnings onlyLow frictionEasy to ignore

Handling a failure

Update the direct package if it has a fix. For a transitive finding, try the closest parent first, then pin a fixed version, and use the NuGet why command to see the path. Suppressing an advisory is a last resort, and Microsoft notes it hides that advisory for every package that shares it.

What a failing build should tell the developer

A bare error code is not enough. The failure message should name the package, the advisory and the fixed version, so the developer can act without searching. NuGet warnings include the advisory link, which helps. If you wrap the audit in a pipeline job, attach the full restore log as an artifact.

Keeping the signal useful

Treat new advisories as a normal event, not an outage. Give the team a short window to act on a new high severity advisory, track the time it takes, and use that number to tune the severity floor. If the pipeline fails often on low value findings, raise the floor. If real issues slip through, lower it.

Quick check

Does restore audit every project in a solution?

Not always. Microsoft documents output properties that let you assert the audited project count matches the restored count.

Where does the vulnerability data come from?

From your audit sources. For nuget.org, the data source is the GitHub Advisory Database.

Safeguard policy gates can block a pull request on dependency findings that meet your rules. A free scan shows what it would flag today.

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.