Package Restore
|
This section documents MSBuild 18.9, the .NET SDK 10.0.402 (with its 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,publishandrunrestore implicitly unless given--no-restore(Restore, Build and Clean). -
msbuild -t:restore/dotnet msbuild -t:restore— the sameRestoretarget, 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-restoredoes 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.
Source: Restore target, Restore outputs.
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 |
|---|---|
|
Replace the configured sources ( |
|
Add sources to the configured ones. |
|
The global-packages folder for this restore. |
|
Use this |
|
Bypass the HTTP cache. |
|
Warn instead of failing when a source is unreachable. |
|
Read-only package folders. |
|
"Excludes fallback folders specified in `RestoreAdditionalProjectFallbackFolders`". |
|
One project at a time. |
|
Re-run even when nothing changed. |
|
"Path to |
|
"Semicolon-delimited list of projects to restore, which should contain absolute paths." |
|
"When the projects are collected via MSBuild it determines whether they are collected using the |
|
Restore output: "Output folder, defaulting to |
|
Lock files (Lock Files and Locked Mode). |
|
Also restore |
|
"`packages.config` only. Specifies the packages directory to which the packages should be restored. |
|
Static graph evaluation (below); still labelled experimental. |
|
The pre-6.12 resolver (Dependency Resolution). |
|
Package pruning, on by default for |
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).
Source: Restore with Azure Pipelines.
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;buildin 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-sourcesin CI — hides an outage until a package is missing. -
Static graph restore with targets that add references dynamically — those references are missed.