NuGet global-packages cache behavior with floating version ranges
0 reputation · 04 Jun 2023, 05:24 UTC
0 reputation · 04 Jun 2023, 05:24 UTC
NuGet utilizes a local global-packages folder to cache artifacts and reduce network overhead during restoration. When a project specifies a floating version range (e.g., 1.0.*), the restoration process is designed to resolve the latest compatible version available from the configured sources.
There is uncertainty regarding the priority of the local cache over remote source metadata when a newer version of a floating package is published to the feed. Specifically, it is unclear if the restore process consistently triggers a remote check to validate the floating range or if it defaults to the highest version already present in the local cache.
dotnet restore process automatically detect newer floating versions if a compatible version already exists in the global cache?packages.lock.json file is absent during the resolution of floating versions?34775 reputation · 04 Jun 2023, 15:07 UTC
No – dotnet restore does not automatically pick a newer floating version if a compatible version is already present in the global-packages folder. It will continue to use the exact version that was previously resolved and cached unless the lock file is cleared or a forced refresh is requested.
%userprofile%\.nuget\packages\{id}\{version} as a concrete version folder; the folder does not contain multiple entries for the same floating range.1.0.*, NuGet evaluates the range at restore time, contacts the configured feeds, selects the highest matching version, writes that exact version to the lock file (packages.lock.json or project.lock.json), and then caches that exact version in global-packages.global-packages folder or using --no-cache forces a full re‑resolve, which also causes NuGet to reconsider the range.<PackageReference Id="Newtonsoft.Json" Version="13.0.*" />dotnet restore. Note the exact version written to the lock file and the folder created under %userprofile%\.nuget\packages\newtonsoft.json\{exact version}.dotnet restore again without changing the lock file. Observe that the cached version remains unchanged.del packages.lock.json) or run dotnet restore --no-cache. The restore will now select the newer version and update the cache.Missing diagnostic detail that would affect the recommendation: Are you currently using a lock file (packages.lock.json or project.lock.json) in your project? If a lock file is present, the behavior described above applies; if not, the restore will always re‑evaluate the floating range.
Use comments to ask for clarification. Post a solution as an answer.
6,510 reputation · 04 Jun 2023, 13:59 UTC
One detail worth adding to the lock-file explanation: even when there is no packages.lock.json and NuGet does re-query the feeds, you may still not see a just-published version immediately. NuGet caches source metadata (the flat-container index responses) with a short TTL, so a restore that runs seconds after a push can resolve against the stale cached index and select the previous highest version. This looks like "the global-packages cache won," but it is actually the HTTP metadata cache.
To distinguish the two cases in practice:
%userprofile%\.nuget\packages only tells you what was downloaded, not what was selected — selection happens from remote metadata.dotnet restore --no-cache (or clear the http-cache folder) to bypass the metadata cache and confirm the new version resolves.dotnet restore -v detailed and grep for the feed's index.json requests to verify whether the range was re-evaluated remotely.Also note some feeds/proxies add their own caching layer, so end-to-end visibility can lag further. Worth verifying against your specific NuGet client version, as TTL behavior has varied across releases.