How to Troubleshoot Developer .NET, Full Fix Guide

Microsoft Fix Intermediate 14 min read Official Docs Grounded Updated April 20, 2026

Why This Is Happening

You open your terminal, type dotnet build, and instead of a clean compile you get something like "A fatal error occurred. The folder [C:\Program Files\dotnet\host\fxr] does not contain any version of libhostfxr.dll" or "It was not possible to find any compatible framework version." I've seen this exact scenario on hundreds of developer machines, and every time, the root cause is slightly different but totally fixable.

The .NET ecosystem has matured enormously, but that maturity has come with complexity. You've got the .NET SDK (the thing you write code with), the .NET Runtime (the thing that runs compiled code), the ASP.NET Core Runtime, the Desktop Runtime on Windows, and they're all versioned independently. A machine running three different projects can easily have four or five different SDK versions installed simultaneously. That's not a bug; that's by design. But it also means things can get tangled fast.

Here's what I see as the most common root causes when developers hit a dotnet troubleshooting wall:

  • Side-by-side SDK conflicts: You installed .NET 8 for a new project but an older project's global.json is pinning to .NET 6. The CLI picks up the wrong SDK and the build explodes.
  • Corrupted PATH environment variable: A Windows update, another SDK installer, or even Visual Studio's own updater silently modified %PATH%, pointing dotnet.exe at the wrong installation directory.
  • NuGet package restore failures: The local cache is stale or a corporate proxy is blocking api.nuget.org, causing errors like NU1101: Unable to find package or error MSB4236.
  • Missing workloads: You're building a MAUI, Blazor WebAssembly, or Wasm project and the required SDK workload was never installed, giving you cryptic errors like NETSDK1147.
  • Incompatible runtime target: The project targets net8.0 but only the .NET 6 runtime is installed on the deployment machine.

Microsoft's error messages in this space are notoriously unhelpful. "Something went wrong" in the .NET CLI output tells you nothing. That's exactly why this guide exists, to cut through the noise and give you the actual path from broken to working.

Browse all Microsoft fix guides →

The Quick Fix, Try This First

Before you spend an hour digging into logs, run this single command in an elevated PowerShell window (right-click PowerShell → Run as administrator):

dotnet --info

This dumps everything, SDK version, runtime versions, RID (Runtime Identifier), OS info, and the working directory's resolved SDK (which may differ from what you expect). Read that output carefully. Nine times out of ten, the problem is already visible here: either you're running the wrong SDK version, a runtime is missing, or the host resolver is pointing at a bad path.

If dotnet --info itself throws an error, "command not found" or "dotnet is not recognized", that means your PATH is broken. Jump directly to Step 2 below.

If the output looks healthy but your build still fails, try this next:

dotnet nuget locals all --clear

This wipes the local NuGet HTTP cache, temporary files, and the global packages cache. It forces a clean restore on the next build. I'd estimate this single command resolves about 30% of "it worked yesterday" dotnet build failures, especially after a VPN change or a network interruption mid-restore.

After clearing, try:

dotnet restore
dotnet build --verbosity detailed

The --verbosity detailed flag is your best friend when things go wrong. It prints every MSBuild property evaluation, every NuGet source check, every target execution. Yes, it's a wall of text, but somewhere in that wall is the exact line telling you what failed and why.

Pro Tip
Always run dotnet --list-sdks and dotnet --list-runtimes before touching any configuration. These two commands give you the full inventory of what's actually installed, which is often very different from what you think is installed. I've seen machines where a developer installed .NET 9 but the project silently kept using .NET 6 because a stale global.json in a parent directory was overriding the SDK selection.
1
Diagnose with dotnet --info and Read the Output

Open PowerShell or Command Prompt, doesn't need elevation for this step, and run:

dotnet --info
dotnet --list-sdks
dotnet --list-runtimes

In the dotnet --info output, look for the section labeled .NET SDKs installed and .NET runtimes installed. Pay close attention to the line that says SDK (reflecting global.json), this tells you which SDK the CLI has actually resolved for your current directory. If this shows an older version than expected, a global.json file somewhere in your directory tree is capping it.

To find that global.json, run this from your project root:

dotnet new globaljson --dry-run

Or just search for it manually:

Get-ChildItem -Path C:\repos -Recurse -Filter "global.json" | Select-Object FullName

Also look at the Host section. The path shown next to Install Location should be C:\Program Files\dotnet\ on Windows (or /usr/share/dotnet/ on Linux). If it's pointing somewhere else, a user-local install, a Visual Studio subfolder, or a Chocolatey path, that's your culprit.

What success looks like: You should see your expected SDK version listed, runtime versions matching your project targets, and no warning messages about framework resolution. If everything here looks correct but builds still fail, move to Step 2.

2
Fix the PATH Environment Variable for dotnet

A broken or incorrect PATH is the number one cause of "dotnet is not recognized" errors and the sneakier problem where the wrong version runs silently. Here's how to verify and correct it.

Open PowerShell and run:

$env:PATH -split ';' | Where-Object { $_ -like '*dotnet*' }

You should see exactly one entry: C:\Program Files\dotnet. If you see multiple dotnet paths, or a path like C:\Program Files\dotnet\x64 or a Visual Studio-internal path like C:\Program Files\Microsoft Visual Studio\2022\Enterprise\dotnet\, that's your problem.

To fix it permanently, open System PropertiesAdvancedEnvironment Variables. Under System variables, find Path and click Edit. Remove any duplicate or incorrect dotnet entries and ensure C:\Program Files\dotnet is present and appears before any Visual Studio entries.

If you want to do this via PowerShell instead:

[System.Environment]::SetEnvironmentVariable(
  "PATH",
  "C:\Program Files\dotnet;" + [System.Environment]::GetEnvironmentVariable("PATH","Machine"),
  "Machine"
)

After changing PATH, close and reopen all terminal windows, environment variables are read at shell startup. Run where dotnet to confirm it now resolves to C:\Program Files\dotnet\dotnet.exe.

What success looks like: dotnet --version returns your expected version number cleanly, with no errors.

3
Repair or Reinstall the .NET SDK

If the PATH is correct but dotnet still misbehaves, throwing errors like "A fatal error occurred, the required library hostfxr.dll could not be found" (error code 0x80070002), your SDK installation is likely corrupted. This happens more than you'd think, especially after failed Windows Updates or aborted Visual Studio installations.

First, try a repair through SettingsApps → search for Microsoft .NET SDK → click the three-dot menu → ModifyRepair. Do this for every .NET SDK and runtime entry you see.

If repair doesn't work, uninstall and reinstall cleanly. Microsoft provides an official uninstall tool, the .NET Uninstall Tool, that removes all versions at once without leaving orphaned files:

# Download from: https://github.com/dotnet/cli-lab/releases
# Run after download:
dotnet-core-uninstall remove --all-previews-but-latest --sdk
dotnet-core-uninstall remove --all-lower-patches --sdk

Then download the latest .NET SDK installer from the official Microsoft .NET download page. I always recommend the x64 installer (not the ARM64 one unless you're on ARM hardware) and the SDK package (not the Runtime-only package, which is deployment-only).

Run the installer as Administrator. After installation, open a new PowerShell window and verify:

dotnet --version
dotnet --info

What success looks like: Clean output, version matches what you installed, no error messages about missing host libraries.

4
Resolve NuGet Package Restore Failures

NuGet restore errors are their own universe of pain. Common ones you'll hit as a developer troubleshooting dotnet issues: NU1101 (package not found), NU1301 (unable to load sources), NU1202 (package not compatible with target framework), and the dreaded MSB4236 (SDK not found).

Start with the cache clear I mentioned in the Quick Fix section, then check your NuGet sources:

dotnet nuget list source

Every source listed there should be reachable. If you're on a corporate network, https://api.nuget.org/v3/index.json may be blocked. You can test it:

Invoke-WebRequest -Uri "https://api.nuget.org/v3/index.json" -UseBasicParsing | Select-Object StatusCode

If this returns an error or times out, your network is the problem, not dotnet. Work with your IT team to whitelist NuGet feeds, or set up a local NuGet mirror using Azure Artifacts or BaGet.

If you have a corporate proxy, configure it for NuGet by adding this to your NuGet.config file (located at %APPDATA%\NuGet\NuGet.Config):

<configuration>
  <config>
    <add key="http_proxy" value="http://your-proxy-server:8080" />
    <add key="http_proxy.user" value="DOMAIN\username" />
  </config>
</configuration>

For NU1202 compatibility errors, open your .csproj file and verify the <TargetFramework> element. A mismatch between net8.0 in your project and a package that only supports up to net7.0 will block restore. Check the package's supported frameworks on nuget.org.

What success looks like: dotnet restore completes with "Restore succeeded" and zero warnings about missing packages.

5
Install Missing SDK Workloads

If you're working on .NET MAUI, Blazor WebAssembly, iOS/Android targets, or WebAssembly-specific features, you'll hit errors like NETSDK1147: To build this project, the following workloads must be installed or error : NU1301 for workload-specific packages. This is one of the most confusing developer dotnet troubleshooting scenarios because the error doesn't always make it obvious that workloads, not packages, are missing.

List your currently installed workloads:

dotnet workload list

Search for what's available:

dotnet workload search maui
dotnet workload search wasm

Install what you need (run as Administrator):

# For .NET MAUI (cross-platform desktop/mobile):
dotnet workload install maui

# For Blazor WebAssembly tools:
dotnet workload install wasm-tools

# For Android-only development:
dotnet workload install android

# For iOS/macOS (on Windows with paired Mac):
dotnet workload install ios maccatalyst

# Update all installed workloads:
dotnet workload update

Workload installation can take several minutes because it downloads platform-specific SDKs and emulators. Don't interrupt the process. If it fails mid-download, run dotnet workload repair to resume from where it left off.

After workload installation, you may need to reload your IDE. In Visual Studio, go to ToolsOptions.NET MAUI and click Check prerequisites to validate the workload was recognized.

What success looks like: dotnet workload list shows your installed workloads, and dotnet build no longer throws NETSDK1147.

Advanced Troubleshooting

You've tried the steps above and something is still broken. I know how frustrating that is, especially when you're staring at a deadline. Let's go deeper.

Using Event Viewer to Diagnose Crash Loops

When a .NET application crashes on startup with no output, or when dotnet.exe itself crashes, Windows Event Viewer records the details. Open Event Viewer (Win+Reventvwr.msc), navigate to Windows LogsApplication, and filter for Source = .NET Runtime or Source = Application Error. Look for Event ID 1026 (.NET Runtime unhandled exception) and Event ID 1000 (application crash). The Faulting Module Name in those entries will often point you directly to a corrupted DLL or a missing assembly.

Forcing a Specific SDK with global.json

In enterprise environments where multiple teams work in the same monorepo, SDK version drift causes build inconsistencies. Pin the SDK version at the repo root:

{
  "sdk": {
    "version": "8.0.404",
    "rollForward": "latestPatch"
  }
}

The rollForward policy matters: latestPatch allows patch-level updates (safe), latestMinor allows minor version bumps, and disable requires an exact match (strictest). I recommend latestPatch for most teams, it keeps you secure without locking you to a single installer artifact.

Domain-Joined and Group Policy Scenarios

On corporate machines managed by Active Directory Group Policy, you may find that dotnet workload install fails with Access Denied (0x80070005) even in an elevated prompt. This happens when GPO restricts software installation outside of approved channels. Check with your IT admin for policies under Computer ConfigurationAdministrative TemplatesWindows ComponentsWindows InstallerProhibit User Installs.

Another common enterprise issue: the DOTNET_ROOT environment variable is set by a Group Policy login script to a network share or a stale path. Override it for your session:

$env:DOTNET_ROOT = "C:\Program Files\dotnet"
$env:PATH = "C:\Program Files\dotnet;" + $env:PATH

Diagnosing with MSBuild Binary Logs

When --verbosity detailed isn't enough, generate a binary log:

dotnet build -bl:build.binlog

Open build.binlog with the free MSBuild Structured Log Viewer tool. It gives you a searchable, visual tree of every property, target, and task in your build, including the exact error location. This is the tool I reach for when a build fails with a property evaluation error and the console output is too truncated to be useful.

When to Call Microsoft Support

If you've verified PATH, reinstalled the SDK, cleared NuGet caches, installed workloads, and the error persists, especially if it's reproducible on a clean VM, it's time to escalate. Document your dotnet --info output, the exact error message and any error codes, your OS version (winver), and whether the machine is domain-joined. Open a support ticket at Microsoft Support. For open-source .NET issues (the CLI, the runtime, NuGet), you can also file a bug directly at the dotnet/sdk or dotnet/runtime GitHub repositories, the team is very responsive.

Prevention & Best Practices

The best dotnet troubleshooting session is the one you never have to have. Here's how senior developers keep their .NET environments clean and stable over time.

Always use global.json at the repo level. Don't rely on "whatever SDK is installed", pin it. When a new team member clones the repo, they'll know immediately if they're missing the right SDK version, rather than getting mysterious build failures three hours into setup.

Keep SDKs current but don't over-install. The .NET team releases Feature Band updates every few months. When you upgrade, use the .NET Uninstall Tool to remove old patch versions of the same major/minor. Keeping .NET 8.0.100, 8.0.200, 8.0.300, and 8.0.400 all installed at once just clutters your environment and creates SDK selection confusion.

Use Visual Studio's built-in SDK management carefully. Visual Studio installs its own .NET SDK bundles during updates. These live in C:\Program Files\Microsoft Visual Studio\2022\[Edition]\sdk\ and can shadow your system-wide installation. If you notice Visual Studio picking up a different SDK than your terminal, check that the VS-internal dotnet path isn't at the front of your PATH.

Test on a clean user profile periodically. Many dotnet issues are user-profile-specific, stale environment variables, per-user NuGet.config settings, corrupted per-user SDK state in %LOCALAPPDATA%\Microsoft\dotnet. Create a fresh local user account and verify your project builds there. If it does, the problem is in your profile, not the system installation.

Automate your dev environment setup. Use a dotnet-tools.json file (local tool manifest) to track CLI tools your project depends on, and include a dotnet tool restore step in your build scripts. This prevents the "it works on my machine" issue where a developer has a global tool installed but a new team member doesn't.

Quick Wins
  • Add global.json to every repo root with an explicit SDK version and "rollForward": "latestPatch"
  • Run dotnet workload update after every major Visual Studio or .NET SDK update
  • Include dotnet nuget locals all --clear in your CI pipeline's clean step to prevent cache poisoning across builds
  • Set DOTNET_CLI_TELEMETRY_OPTOUT=1 in your system environment variables if you're on a slow network, this eliminates telemetry-related startup lag in the CLI

Frequently Asked Questions

Why does "dotnet build" work in Visual Studio but fail in the terminal?

This is almost always a PATH discrepancy. Visual Studio ships with its own internal .NET SDK and MSBuild binaries, and it uses those when building inside the IDE. Your terminal, meanwhile, uses whatever dotnet.exe is first on your system PATH. Run where dotnet in your terminal to see exactly which executable it's hitting. Then compare that SDK version against what Visual Studio reports under Help → About Microsoft Visual Studio → .NET Framework. If they're different, that's your answer, pin the version with global.json or ensure both paths point to the same SDK.

What does "The framework 'Microsoft.NETCore.App', version '8.0.0' was not found" actually mean?

It means the machine trying to run your application has the .NET SDK installed (or nothing installed), but not the specific .NET Runtime version your app was compiled against. The SDK is for building; the Runtime is for running. On a production server or a user's machine, you typically only need the Runtime, download the correct version of the .NET Runtime or ASP.NET Core Runtime (not the SDK) from the Microsoft .NET download page. Alternatively, publish your app as self-contained (dotnet publish --self-contained true -r win-x64) to bundle the runtime inside your executable.

My dotnet restore keeps failing with NU1301, what's the fastest fix?

NU1301 means NuGet couldn't read from one of your configured package sources. The fastest diagnosis is dotnet nuget list source, check every listed source and verify it's accessible. In corporate environments, api.nuget.org is often blocked by a firewall or proxy. Try hitting the URL in your browser; if it loads, the issue is proxy configuration in NuGet. Add your proxy settings to %APPDATA%\NuGet\NuGet.Config as shown in Step 4 above. If your company runs an internal NuGet feed (Artifactory, Azure Artifacts, etc.), make sure that source is listed and that your credentials are valid, run dotnet nuget update source [name] --username [user] --password [token] to refresh them.

Can I have multiple .NET versions installed at the same time, and is that safe?

Yes, in fact, it's the intended design and completely safe. .NET supports true side-by-side installation. You can have .NET 6, .NET 7, .NET 8, and .NET 9 all on the same machine, and each project will use whichever version it targets. The dotnet CLI resolves the correct runtime automatically at execution time. The only thing you need to manage is which SDK the CLI selects at build time, that's what global.json controls. Where people get into trouble is when they have multiple patch versions of the same SDK (e.g., 8.0.100, 8.0.200, 8.0.300) and no global.json pinning. In that case, the CLI defaults to the latest installed SDK, which can change behavior unexpectedly when you install a new patch.

dotnet publish works locally but the app crashes on the server, how do I debug it?

First, check the server's Application event log (Event ID 1026 or 1000) for the exact exception. If you see "Could not load file or assembly" errors, you're likely missing a runtime dependency or the wrong .NET Runtime version is installed on the server. Run dotnet --list-runtimes on the server and compare against your app's target framework. If the runtime is present but the crash persists, enable stdout logging in your web.config (for IIS-hosted apps): set stdoutLogEnabled="true" and specify a valid stdoutLogFile path. This captures startup exceptions that IIS otherwise swallows. For non-IIS deployments, set the environment variable DOTNET_ENVIRONMENT=Development temporarily to get detailed error pages.

What is NETSDK1138 and how do I fix it?

NETSDK1138: The target framework 'net9.0' is out of support, or similarly for net5.0, net6.0, means your project is targeting an end-of-life .NET version. Microsoft follows a predictable release and support cycle: even-numbered major versions (6, 8, 10) are Long-Term Support (LTS) with 3 years of support; odd-numbered versions (5, 7, 9) are Standard Term Support with 18 months. The fix is to update your <TargetFramework> in the .csproj file to a supported version. For example, change <TargetFramework>net6.0</TargetFramework> to <TargetFramework>net8.0</TargetFramework>. Then install the matching SDK and run dotnet build. In most cases, the upgrade is straightforward, check the official .NET migration guides for any breaking API changes between versions.

Related Microsoft Fix Guides

H
Sai Kiran Pandrala
Our team includes certified Microsoft engineers, Azure architects, and system administrators with 10+ years of enterprise IT experience. Every guide is written from hands-on troubleshooting, not guesswork. We test every fix before publishing.