Skip to content
Latchkey

NuGet "--locked-mode" Restore Mismatch in CI

CI restored with --locked-mode (or RestoreLockedMode=true), which forbids changing the lock file. The resolved graph differs from the committed packages.lock.json, so restore fails rather than silently updating the lock.

What this error means

A dotnet restore --locked-mode step fails saying the lock cannot be modified in locked mode, after a dependency change that was not re-locked. Removing --locked-mode "fixes" it locally, which confirms the lock is stale.

dotnet restore output
error : The packages lock file is inconsistent with the project dependencies so
restore can't be run in locked mode. Disable RestoreLockedMode or pass
--force-evaluate to update the lock file.

Common causes

Dependencies changed without regenerating the lock

A PackageReference or a central PackageVersion changed, but packages.lock.json was not refreshed, so locked-mode restore detects the drift and stops.

A transitive bump changed the resolved graph

Even without a direct edit, a newly published transitive version (with a floating range) can change the resolved set, making the committed lock stale under locked mode.

How to fix it

Regenerate and commit the lock file

Re-evaluate to refresh the lock, then commit it so locked-mode CI matches.

Terminal
dotnet restore --force-evaluate
git add **/packages.lock.json && git commit -m "Refresh NuGet lock file"

Keep locked mode strict in CI

Restore in locked mode so a PR that forgets to re-lock fails fast instead of drifting.

.github/workflows/ci.yml
dotnet restore --locked-mode
# or set per project:
# <RestoreLockedMode>true</RestoreLockedMode>

How to prevent it

  • Run dotnet restore --force-evaluate after any dependency change and commit the lock.
  • Enable RestorePackagesWithLockFile and keep packages.lock.json committed.
  • Avoid floating version ranges when you rely on locked-mode reproducibility.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →