NETSDK1045: The Current .NET SDK Does Not Support Targeting This Version

NETSDK1045 means the SDK actually selected by the failing build cannot target the framework the project resolves to. Do not immediately install another SDK, downgrade TargetFramework, or delete global.json. First prove the requested target, the SDK the failing environment selected, and why it selected that SDK.

.NET · NETSDK1045 · SDK selectionCLI · Visual Studio · CI · DockerLast reviewed Sep 27, 2026
🎯 You’re likely in the right place if:
Your build says The current .NET SDK does not support targeting a newer .NET version.The required SDK appears installed, but the build still reports an older SDK.The project works in one terminal/machine but fails in Visual Studio, CI, Docker, or another architecture.
Start from what the failing build is actually using
SDK missingThe target is intentional, but no compatible SDK is installed in the failing environment.
SDK installed, wrong one selectedCheck dotnet --version, global.json, PATH, architecture and MSBuild overrides.
CLI works, IDE failsCheck the IDE/MSBuild toolchain and preview support instead of assuming both use the same SDK context.
Local works, CI/Docker failsInspect the runner/container image and execute diagnostics inside that exact environment.
Target framework is accidentalTrace TargetFramework/TargetFrameworks and inherited MSBuild properties before retargeting.
Difficulty: ModerateRisk: low if diagnosis precedes retargeting
🔎 First check — selected SDK is not the same question as installed SDKs
dotnet --version dotnet --info dotnet --list-sdks

dotnet --version tells you which SDK this invocation selected. --list-sdks tells you which SDKs are visible to that dotnet host/architecture. Compare the selected SDK with the project's target framework before changing anything. Treat --list-sdks as architecture-scoped inventory, not proof of which SDK a build selected.

Guardrail: never install, downgrade, or retarget .NET blindly. First prove which SDK the failing build is actually using and why that SDK was selected.
ADSENSE · reserved slot after the first useful step

30-second decision

1
Does dotnet --version show an SDK capable of your intended target?
No → determine whether the SDK is missing or selection is pinned. Yes → compare the failing build context; your IDE/CI may be selecting differently.
2
Does dotnet --list-sdks include the SDK you expect?
No → check installation and host architecture. Yes → it proves only that this dotnet architecture can see the SDK; use dotnet --version in the failing invocation context to diagnose selection.
3
Is there a global.json above the working directory/solution?
Do not check only the repository root. Search the relevant ancestor chain: CLI and MSBuild can start that search from different directories.
4
Only Visual Studio, CI or Docker fails?
Run the evidence commands inside that failing environment. A successful local CLI build does not prove the other environment uses the same SDK.

Step 1 — prove the effective target framework

Open the failing project and identify TargetFramework or TargetFrameworks. NETSDK1045 is about a mismatch between the target the project resolves to and the capability of the selected SDK.

<PropertyGroup> <TargetFramework>net8.0</TargetFramework> </PropertyGroup>

Do not assume the value lives only in the project file. Directory.Build.props can set properties for projects below it, and repository build logic can make the effective target differ from what you first notice.

Verify: record the target framework that the failing project is intended to build. If the target itself is accidental, correct the project/build property. If it is intentional, keep it and diagnose SDK selection.

Step 2 — prove the SDK selected in the failing context

dotnet --version dotnet --info

Run these from the same working directory and environment used by the failing build. SDK selection can depend on configuration discovered from that location. A command run from your home directory is weak evidence for a build launched from a repository or solution.

Verify: the selected SDK major/minor is compatible with the target you intend to build. If an older SDK is selected despite a newer one being installed, continue to global.json and environment overrides.

Fix #1 — find the global.json that actually controls selection

global.json can pin an SDK and control roll-forward. The important trap is location: .NET searches upward through ancestor directories. The CLI muxer starts its search from the current working directory. The MSBuild project SDK resolver starts from the solution directory when a solution exists; otherwise from the project directory, and falls back to the working directory when neither applies. Both search upward through ancestor directories. That difference can make a terminal command and an IDE/MSBuild build discover different global.json files.

Important: global.json selects an SDK; it does not set the project's target framework. Its version is a full SDK version and rollForward controls which installed SDKs may satisfy that request. Do not change either until you know the repository's intended SDK policy.
{ "sdk": { "version": "8.0.302", "rollForward": "latestFeature" } }

Do not automatically delete a repository's SDK pin. It may exist to make developer and CI builds reproducible. Decide whether the pin is stale, intentional, or needs an appropriate roll-forward policy.

Verify: run dotnet --version from the same working directory as the failing CLI invocation. For an IDE/MSBuild-only failure, also verify the solution/project context because its resolver search can begin elsewhere. The selected SDK should satisfy the repository's intended policy—not merely be the newest SDK on the machine.

Fix #2 — if the required SDK is genuinely missing, install the SDK, not just the runtime

If the target is correct and no compatible SDK appears in dotnet --list-sdks, install the appropriate .NET SDK in that environment. A runtime installation is not a substitute for the SDK required to compile the project.

Keep target intent separate from machine state. Retargeting a project to an older framework just because one workstation lacks the intended SDK changes the application target. If the project intentionally targets the newer framework, repair the build environment instead.

Verify: restart the relevant terminal/IDE if necessary, then confirm the compatible SDK appears and is selected before rebuilding.

Fix #3 — check x86/x64/Arm64 when “the SDK is installed” but invisible

dotnet --list-sdks reports SDKs visible for the architecture of the invoked dotnet. On Windows, SDK visibility depends on the architecture of the invoked dotnet; x86, x64 and Arm64 contexts can therefore expose different inventories. A build using another host architecture can miss an SDK that exists elsewhere on the same machine.

where dotnet dotnet --info dotnet --list-sdks

On .NET 10 and later, the CLI also supports architecture-aware listing with --arch. Do not copy that option into older SDK environments where it is unavailable.

Verify: the host architecture used by the failing build can see the intended SDK.

Fix #4 — CLI works but Visual Studio fails

Do not treat a successful terminal build as proof that Visual Studio is using an equivalent toolchain. Visual Studio version/support, its MSBuild environment, and preview-SDK settings can affect whether the target SDK is usable. If the only compatible SDK is a preview, Visual Studio may also require preview SDK usage to be enabled.

Verify: close/restart Visual Studio after SDK/configuration changes and rebuild the same solution/configuration. If CLI and IDE still disagree, capture the SDK/MSBuild environment from the failing IDE build rather than reinstalling SDKs repeatedly.

Fix #5 — remove stale PATH or MSBuildSDKPath overrides only when proven

An old direct SDK path in PATH can route the build toward older tooling. MSBuildSDKPath is even more direct: when set, MSBuild can use it instead of normal SDK resolution.

where dotnet echo %MSBuildSDKPath%

On PowerShell, inspect $env:MSBuildSDKPath. On Linux/macOS, use which -a dotnet and printenv MSBuildSDKPath. Do not delete environment variables just because they exist; determine whether your build tooling intentionally sets them.

Verify: open a fresh shell/build process, confirm the expected host and SDK selection, then rebuild.

Fix #6 — inspect Directory.Build.props and inherited target settings

If the SDK selection looks correct but NETSDK1045 still reports an unexpected target, inspect Directory.Build.props up the repository hierarchy and other imported build configuration. These files can set TargetFramework or related properties for multiple projects.

Reader trap: changing the visible .csproj may do nothing if another imported property determines the effective target, or may create a project-specific exception that hides the repository's intended build policy.

Verify: rebuild after correcting the property at its owning configuration layer and confirm the error now names the intended target—or disappears.

Fix #7 — local works, CI or Docker fails

Run the same three evidence commands inside the runner or container that fails. The host machine's SDK inventory is irrelevant when the build executes in a container image or hosted runner with a different SDK set.

dotnet --version dotnet --info dotnet --list-sdks

Then compare the repository's global.json, CI SDK setup action/task, working directory, architecture and environment overrides. For Docker multi-stage builds, inspect the stage that actually runs restore/build/publish. The final runtime image may intentionally contain no SDK at all, so running --list-sdks there does not diagnose NETSDK1045 from an earlier build stage.

Docker decision: if FROM .../sdk:<version> performs the build, align that SDK image with the intended target and repository SDK policy. Do not “fix” the final aspnet/runtime image by adding an SDK merely because compilation failed in another stage.

Verify: the failing CI/container selects the same intended SDK policy as the validated development build, then run the exact pipeline/build target again.

Fix #8 — preview SDK installed but not selected

A preview SDK can be present without being eligible in every invocation context. global.json supports allowPrerelease, and Visual Studio's behavior also depends on whether preview SDK use is enabled. If the project intentionally targets a preview toolchain, make that intent explicit rather than relying on accidental machine state.

Verify: dotnet --version and the IDE/build environment both select the intended preview SDK before rebuilding.

What not to do

Do not downgrade TargetFramework merely to silence NETSDK1045 unless the product really should target the older framework.Do not delete global.json before understanding why the repository pins an SDK.Do not treat dotnet --list-sdks as SDK-selection evidence. It is architecture-scoped inventory; selection must be checked with dotnet --version in the relevant invocation context.Do not confuse an installed .NET runtime with an installed .NET SDK.Do not repeatedly reinstall SDKs when dotnet --version proves an older SDK is being selected by configuration.Do not remove MSBuildSDKPath or PATH entries without checking whether build tooling intentionally owns them.Do not use a local success to dismiss a CI/IDE failure; compare the actual build environments.Do not inspect only a Docker final/runtime stage when restore/build/publish happens in an earlier SDK stage.Do not retarget to an older framework until you have confirmed that the older target is a product requirement—not merely a workaround for a missing or mis-selected SDK.

Final verification — prove selection, then rebuild

dotnet --version dotnet --info dotnet --list-sdks dotnet clean dotnet build

A clean build is useful only after the selection problem is corrected. The success condition is not “a newer SDK exists somewhere”; it is that the exact failing environment selects an SDK compatible with the project's intentional target and completes the build.

Still seeing NETSDK1045?

Before escalating, capture:complete NETSDK1045 line and project patheffective TargetFramework/TargetFrameworksdotnet --version, dotnet --info and dotnet --list-sdks from the failing environmentglobal.json found along the relevant CLI and solution/project ancestor search paths, plus its version, rollForward and allowPrerelease policywhere dotnet/which -a dotnet and host architectureMSBuildSDKPath if setrelevant Directory.Build.propswhether failure is CLI, Visual Studio, CI or Docker only

Official references

Still stuck? Ask the community

Share the exact target, selected SDK and failing environment—not only the NETSDK1045 wrapper line.

Keep it safe: redact repository URLs, tokens, internal paths, environment secrets and private package feeds.
Powered by GitHub DiscussionsSign in with GitHub to comment. Reading comments does not require sign-in.

Loading community discussion…