Skip to content

Add recommendation to pin .NET SDK version#3571

Open
Frulfump wants to merge 3 commits into
NuGet:mainfrom
Frulfump:patch-1
Open

Add recommendation to pin .NET SDK version#3571
Frulfump wants to merge 3 commits into
NuGet:mainfrom
Frulfump:patch-1

Conversation

@Frulfump

@Frulfump Frulfump commented May 1, 2026

Copy link
Copy Markdown

Fix NuGet/Home#14867
Added a note about pinning the .NET SDK version to ensure consistency in the dependency graph.

Added a note about pinning the .NET SDK version to ensure consistency in the dependency graph.
@Frulfump
Frulfump requested review from a team as code owners May 1, 2026 06:32
@learn-build-service-prod

Copy link
Copy Markdown

PoliCheck Scan Report

The following report lists PoliCheck issues in PR files. Before you merge the PR, you must fix all severity-1 and severity-2 issues. The AI Review Details column lists suggestions for either removing or replacing the terms. If you find a false positive result, mention it in a PR comment and include this text: #policheck-false-positive. This feedback helps reduce false positives in future scans.

✅ No issues found

More information about PoliCheck

Information: PoliCheck | Severity Guidance | Term
For any questions: Try searching the learn.microsoft.com contributor guides or post your question in the Learn support channel.

@learn-build-service-prod

Copy link
Copy Markdown

Learn Build status updates of commit 5a381eb:

⚠️ Validation status: warnings

File Status Preview URL Details
docs/consume-packages/Package-References-in-Project-Files.md ⚠️Warning View Details

docs/consume-packages/Package-References-in-Project-Files.md

  • Line 344, Column 134: [Warning: hard-coded-locale - See documentation] Link 'https://learn.microsoft.com/en-us/dotnet/core/tools/global-json' contains locale code 'en-us'. For localizability, remove 'en-us' from links to most Microsoft sites.
  • Line 344, Column 279: [Warning: hard-coded-locale - See documentation] Link 'https://learn.microsoft.com/en-us/dotnet/core/tools/global-json' contains locale code 'en-us'. For localizability, remove 'en-us' from links to most Microsoft sites.
  • Line 344, Column 134: [Suggestion: docs-link-absolute - See documentation] Absolute link 'https://learn.microsoft.com/en-us/dotnet/core/tools/global-json' will be broken in isolated environments. Replace with a relative link.
  • Line 344, Column 279: [Suggestion: docs-link-absolute - See documentation] Absolute link 'https://learn.microsoft.com/en-us/dotnet/core/tools/global-json' will be broken in isolated environments. Replace with a relative link.

For more details, please refer to the build report.

Note: Your PR may contain errors or warnings or suggestions unrelated to the files you changed. This happens when external dependencies like GitHub alias, Microsoft alias, cross repo links are updated. Please use these instructions to resolve them.

@Frulfump

Frulfump commented May 1, 2026

Copy link
Copy Markdown
Author

@dotnet-policy-service agree

@Frulfump

Frulfump commented May 1, 2026

Copy link
Copy Markdown
Author

Comment thread docs/consume-packages/Package-References-in-Project-Files.md Outdated
@learn-build-service-prod

Copy link
Copy Markdown

Learn Build status updates of commit 31e441b:

✅ Validation status: passed

File Status Preview URL Details
docs/consume-packages/Package-References-in-Project-Files.md ✅Succeeded View

For more details, please refer to the build report.

@learn-build-service-prod

Copy link
Copy Markdown

PoliCheck Scan Report

The following report lists PoliCheck issues in PR files. Before you merge the PR, you must fix all severity-1 and severity-2 issues. The AI Review Details column lists suggestions for either removing or replacing the terms. If you find a false positive result, mention it in a PR comment and include this text: #policheck-false-positive. This feedback helps reduce false positives in future scans.

✅ No issues found

More information about PoliCheck

Information: PoliCheck | Severity Guidance | Term
For any questions: Try searching the learn.microsoft.com contributor guides or post your question in the Learn support channel.

- A given package version is removed from the repository. Though nuget.org does not allow package deletions, not all package repositories have this constraint. This results in NuGet finding the best match when it cannot resolve to the deleted version.

> [!Note]
> It's also recommended to pin the version of the .NET SDK that's used so the SDK version and dependency graph stay in lockstep. See [global.json](/dotnet/core/tools/global-json) and especially the `rollForward` section with the `disable` value [global.json rollForward Policy](/dotnet/core/tools/global-json). For related issues when not pinning, see [ASP.NET Core GitHub issue](https://github.com/dotnet/aspnetcore/issues/65061) and [.NET Core SDK GitHub issue](https://github.com/dotnet/sdk/issues/48795)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how to validate the relative links as they give me a 404 but the validation bot says everything is green, I'd still like to verify for myself

Comment thread docs/consume-packages/Package-References-in-Project-Files.md Outdated
@learn-build-service-prod

Copy link
Copy Markdown

PoliCheck Scan Report

The following report lists PoliCheck issues in PR files. Before you merge the PR, you must fix all severity-1 and severity-2 issues. The AI Review Details column lists suggestions for either removing or replacing the terms. If you find a false positive result, mention it in a PR comment and include this text: #policheck-false-positive. This feedback helps reduce false positives in future scans.

✅ No issues found

More information about PoliCheck

Information: PoliCheck | Severity Guidance | Term
For any questions: Try searching the learn.microsoft.com contributor guides or post your question in the Learn support channel.

@learn-build-service-prod

Copy link
Copy Markdown

Learn Build status updates of commit f85e84a:

✅ Validation status: passed

File Status Preview URL Details
docs/consume-packages/Package-References-in-Project-Files.md ✅Succeeded View

For more details, please refer to the build report.

- A given package version is removed from the repository. Though nuget.org does not allow package deletions, not all package repositories have this constraint. This results in NuGet finding the best match when it cannot resolve to the deleted version.

> [!Note]
> It's also recommended to pin the version of the .NET SDK that's used so the SDK version and dependency graph stay in lockstep. See [global.json](/dotnet/core/tools/global-json) and especially the `rollForward` section with the `disable` value [global.json rollForward Policy](/dotnet/core/tools/global-json#rollforward). For related issues when not pinning, see [ASP.NET Core GitHub issue](https://github.com/dotnet/aspnetcore/issues/65061) and [.NET Core SDK GitHub issue](https://github.com/dotnet/sdk/issues/48795)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have too many notes, so let's have this content as just a regular paragraph.
Let's do one sentence per line.

My take on this is that I think we should provide some explanation on the motivation. The SDK version pinning is something customers may need, but I don't necessarily want customers using lock file to be tying themselves to potentially older versions of the SDK unless they absolutely needed.

So in there I'd basically talk about the fact that .NET SDK wills ometimes automatically reference packages and those package versions may change as the .NET SDK tooling changes and when customers see these issues, then they should pin.

cc @baronfel for a gut check.

@Frulfump Frulfump May 1, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can reformat.

More explanations are always good, for lock files specifically it might be the current (see below) recommendation but for things like reproducible build (outside of this document but somewhat related?) it would still make sense to pin the version used. Yes for those not using tools like Depandbot or Renovate it might be more easily missed but with knowledgeable/skilled devs you would always check global.json when first starting to check out a new repo. (Maybe something should be built(built-in) that warns when the SDK contains known vulns or is just outdated? Both CLI and IDE (Visual Studio(/Rider)) (and VS Code))

It's based on this comment from Chet ~1 year ago dotnet/sdk#48795 (comment)

It's the recommended way today, but it is a gap in the overall NuGet lockfile story. Our current recommendation for users that use lock files is to also lock their SDK versions via global.json with no rollforward, so they(sic) their entire toolchain stays in lockstep.

But yeah very interested in hearing Chet's updated takes here, will give it some time before making any adjustments

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@baronfel
Do you have any guidance here?

@dotnet-policy-service

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has no activity for 30 days. It will be closed if no further activity occurs within another 330 days of this comment. If it is closed, you may reopen it anytime when you're ready again, as long as you don't delete the branch.

@Nigusu-Allehu
Nigusu-Allehu requested a review from zivkan June 9, 2026 23:26
- A given package version is removed from the repository. Though nuget.org does not allow package deletions, not all package repositories have this constraint. This results in NuGet finding the best match when it cannot resolve to the deleted version.

> [!Note]
> It's also recommended to pin the version of the .NET SDK that's used so the SDK version and dependency graph stay in lockstep. See [global.json](/dotnet/core/tools/global-json) and especially the `rollForward` section with the `disable` value [global.json rollForward Policy](/dotnet/core/tools/global-json#rollforward). For related issues when not pinning, see [ASP.NET Core GitHub issue](https://github.com/dotnet/aspnetcore/issues/65061) and [.NET Core SDK GitHub issue](https://github.com/dotnet/sdk/issues/48795)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry it took me so long to review. I've had time management challenges following a week of being sick. Anyway, I don't like that this is suggesting everyone who uses lock files to also use a global.json. This issue only affects a limited set of project types. For example, I did dotnet new mvc, and that project didn't have any implicit package references, so those projects don't gain any benefits from locking the sdk via global.json, and only have the downsides.

Here's my suggestion:

Suggested change
> It's also recommended to pin the version of the .NET SDK that's used so the SDK version and dependency graph stay in lockstep. See [global.json](/dotnet/core/tools/global-json) and especially the `rollForward` section with the `disable` value [global.json rollForward Policy](/dotnet/core/tools/global-json#rollforward). For related issues when not pinning, see [ASP.NET Core GitHub issue](https://github.com/dotnet/aspnetcore/issues/65061) and [.NET Core SDK GitHub issue](https://github.com/dotnet/sdk/issues/48795)
> For some project types, the .NET SDK adds implicit `PackageReference` items, and using a different SDK version will change the package version, leading to locked mode restore failures.
> To mitigate this issue, you can use a [global.json file](/dotnet/core/tools/global-json), setting the [global.json rollForward Policy](/dotnet/core/tools/global-json#rollforward) to disable.
> This means that all developers working in this repo, and your CI pipelines, will need to use the same version of the SDK at all times, but it allows you to control when the implicit packages change versions.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah no worries. Sure that's fine I'll take your suggestion but still interested in the SDK teams thoughts as well and it's not Only downside as you get a guaranteed version of the SDK and the risk for issues is more limited then when compared to rolling forward. There's been cases of new warnings or other bugs in new patch versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Lock file docs should mention it's recommended to use global.json with rollForward = disable when using lock files

3 participants