Package Restore

This section documents MSBuild 18.9, the .NET SDK 10.0.402 (with its dotnet CLI) and NuGet 7.9, as published in the MSBuild, .NET and NuGet documentation on learn.microsoft.com, which is the reference these pages are written and verified against. Material about .NET 11 / NuGet 8.0 is still in preview and is always flagged as such — never presented as baseline.

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The C# Reference bibliography lists the reference material consulted while preparing these pages.

Restore turns a project’s PackageReference items into a resolved graph, makes sure every package of that graph is in the global-packages folder, and writes the files the build reads. This page covers how restore is invoked, the properties that control it and the errors it reports, with NuGet 7.9.0 in .NET SDK 10.0.402. The machinery of a single package install is on How Package Installation Works.

Three ways to run it

  • dotnet restore — the command; dotnet build, test, pack, publish and run restore implicitly unless given --no-restore (Restore, Build and Clean).

  • msbuild -t:restore / dotnet msbuild -t:restore — the same Restore target, run as an MSBuild target:

      Determining projects to restore...
      Restored ~/inst/Inst.csproj (in 487 ms).
  • msbuild -restore -t:build — restore and build in one invocation. Not -t:restore;build: the build must evaluate the project after restore has written its imports, which -restore does as a separate evaluation.

Visual Studio restores automatically before builds (the packageRestore settings), and nuget.exe restore also handles packages.config projects.

What restore writes

obj/Inst.csproj.nuget.dgspec.json   the restore inputs (dependency graph spec)
obj/Inst.csproj.nuget.g.props       imports from packages' build/*.props, Pkg* properties
obj/Inst.csproj.nuget.g.targets     imports from packages' build/*.targets
obj/project.assets.json             the resolved graph and selected assets
obj/project.nuget.cache             the no-op check: a hash of the inputs
packages.lock.json                  next to the project, with RestorePackagesWithLockFile

When project.nuget.cache shows that nothing changed, restore is a no-op (milliseconds); --force / RestoreForce re-runs it anyway.

Restore properties

Every property can be set in a project, in Directory.Build.props, or with -p: on the command line; most have a dotnet restore option too.

Property Effect

RestoreSources

Replace the configured sources (;-separated). --source.

RestoreAdditionalProjectSources

Add sources to the configured ones.

RestorePackagesPath

The global-packages folder for this restore. --packages.

RestoreConfigFile

Use this nuget.config only. --configfile.

RestoreNoHttpCache

Bypass the HTTP cache. --no-http-cache.

RestoreIgnoreFailedSources

Warn instead of failing when a source is unreachable. --ignore-failed-sources.

RestoreFallbackFolders, RestoreAdditionalProjectFallbackFolders

Read-only package folders.

RestoreAdditionalProjectFallbackFoldersExcludes

"Excludes fallback folders specified in `RestoreAdditionalProjectFallbackFolders`".

RestoreDisableParallel

One project at a time. --disable-parallel.

RestoreForce

Re-run even when nothing changed. --force.

RestoreTaskAssemblyFile

"Path to NuGet.Build.Tasks.dll."

RestoreGraphProjectInput

"Semicolon-delimited list of projects to restore, which should contain absolute paths."

RestoreUseSkipNonexistentTargets

"When the projects are collected via MSBuild it determines whether they are collected using the SkipNonexistentTargets optimization. When not set, defaults to true. The consequence is a fail-fast behavior when a project’s targets cannot be imported."

MSBuildProjectExtensionsPath

Restore output: "Output folder, defaulting to BaseIntermediateOutputPath and the obj folder" — where project.assets.json and the <project>.nuget.g.props/.targets files are written (above).

RestorePackagesWithLockFile, RestoreLockedMode, RestoreForceEvaluate, NuGetLockFilePath

Lock files (Lock Files and Locked Mode).

RestorePackagesConfig

Also restore packages.config projects with msbuild -t:restore (MSBuild 16.5+, not dotnet).

RestoreRepositoryPath

"`packages.config` only. Specifies the packages directory to which the packages should be restored. SolutionDirectory will be used if not specified."

RestoreUseStaticGraphEvaluation

Static graph evaluation (below); still labelled experimental.

RestoreUseLegacyDependencyResolver

The pre-6.12 resolver (Dependency Resolution).

RestoreEnablePackagePruning

Package pruning, on by default for net10.0+ (PackageReference).

Quoted descriptions are the NuGet documentation’s own wording. The restore-properties table in the NuGet documentation omits RestoreEnablePackagePruning and the NuGetAudit properties (NuGetAudit, NuGetAuditMode, NuGetAuditLevel), which are documented on the pruning and audit pages.

Overriding the sources does not force downloads: dotnet restore --force -p:RestoreSources=~/srcs/hfeed, pointing at a folder that does not contain Humanizer.Core, still succeeded (Restored ~/inst/Inst.csproj (in 230 ms)) because the package was already in the global-packages folder, which restore checks first. To prove a restore works from the configured sources alone, use an empty RestorePackagesPath.

Static graph restore

By default restore evaluates every project, running MSBuild targets to collect references. With RestoreUseStaticGraphEvaluation=true it reads the project graph with MSBuild’s static graph API instead (Parallel, Graph and Server Builds):

dotnet restore Ledgerline.slnx --force -p:RestoreUseStaticGraphEvaluation=false
dotnet restore Ledgerline.slnx --force -p:RestoreUseStaticGraphEvaluation=true
static=false 2.66 s
static=true  1.94 s

(six projects, wall-clock time after dotnet build-server shutdown). The gain grows with repository size. Custom targets that add PackageReference items at build time are invisible to static evaluation.

Replacing one library in the graph

When a package brings an assembly that must be replaced by a local build, exclude the package’s assets and reference the file directly:

<PackageReference Include="Newtonsoft.Json" Version="9.0.1">
  <ExcludeAssets>All</ExcludeAssets>
</PackageReference>
<Reference Include="Newtonsoft.Json.dll" />

The package still takes part in version resolution, so other packages keep seeing the version they expect.

Restore in Azure Pipelines

The DotNetCoreCLI@2 task with command: restore runs dotnet restore; for authenticated Azure Artifacts feeds, run NuGetAuthenticate@1 first so the credential provider has a token. A Visual Studio "restore on build" setting has no effect on a pipeline (CI Builds and Caching).

Restore errors

Reproduced on the scratch project with Ledgerline's source mapping (Ledgerline.* from the local folder only):

NU1101 — no package with that ID:

~/ledgerline/samples/Deps/Deps.csproj : error NU1101: Unable to find package Ledgerline.Nonexistent. No packages exist with this id in source(s): ledgerline-local. PackageSourceMapping is enabled, the following source(s) were not considered: ledgerline-bagetter, nuget.org.

NU1102 — the ID exists, no version satisfies the range (Version="2.1.0", only 2.1.0-beta.1 is above 2.0.0):

~/ledgerline/samples/Deps/Deps.csproj : error NU1102: Unable to find package Ledgerline.Money with version (>= 2.1.0)
~/ledgerline/samples/Deps/Deps.csproj : error NU1102:   - Found 4 version(s) in ledgerline-local [ Nearest version: 2.1.0-beta.1 ]

NU1103 — only prereleases satisfy it (Ledgerline.Preview has only 1.0.0-beta.1; Version="0.9.0"):

~/ledgerline/samples/Deps/Deps.csproj : error NU1103: Unable to find a stable package Ledgerline.Preview with version (>= 0.9.0)
~/ledgerline/samples/Deps/Deps.csproj : error NU1103:   - Found 1 version(s) in ledgerline-local [ Nearest version: 1.0.0-beta.1 ]

With Version="1.0.0" the same package gave NU1102, not NU1103: 1.0.0-beta.1 sorts below 1.0.0, so it is not a candidate at all.

NU1301 — a source cannot be reached (a nuget.config with only https://localhost:9/v3/index.json):

~/ledgerline/samples/Deps/Deps.csproj : error NU1301: Unable to load the service index for source https://localhost:9/v3/index.json.
~/ledgerline/samples/Deps/Deps.csproj : error NU1301:   Connection refused (localhost:9)

--ignore-failed-sources turns NU1301 into a warning, which only helps when another source has every package. "Assets file not found" (NETSDK1004) after a failed restore means the build ran without one (Troubleshooting SDK Errors).

Common mistakes

  • -t:restore;build in one target list — the build evaluates stale imports; use -restore.

  • Testing a source change with a warm global-packages folder — nothing is downloaded.

  • --ignore-failed-sources in CI — hides an outage until a package is missing.

  • Static graph restore with targets that add references dynamically — those references are missed.