DeployHQ ships seven .NET SDK series in the build environment, selectable per project. This article covers which versions are available, how to pick one, and how `global.json` is handled at build time.

## What's new in June 2026

- **.NET 10.0 LTS** is now available and is the default for new projects, and for projects set to **Use the latest stable version**. Microsoft supports .NET 10.0 until 2028-11-14.
- All other SDK series have been updated to their latest patches. The pinned versions are now real SDK versions (previously they were runtime versions, which weren't quite the right thing to advertise).
- `global.json` at the repository root is now respected.
- `DOTNET_CLI_TELEMETRY_OPTOUT=1` is set on every build, so the .NET CLI no longer sends usage data to Microsoft.
- `DOTNET_ROOT` is now exported correctly, so child processes spawned by `dotnet tool install`, `dotnet publish`, MSBuild, and similar tools find the SDK reliably.

## Choosing a .NET SDK version

Head to your project's **Build Configuration** and look for the **Language Versions** section. The .NET dropdown offers:

- **Use the latest stable version (.NET 10.0)** -- recommended; your project follows whatever we ship as the latest stable series.
- **.NET 10.0 (currently 10.0.301)**
- **.NET 9.0 (currently 9.0.315)**
- **.NET 8.0 (currently 8.0.422)**
- **.NET 7.0 (currently 7.0.410)**
- **.NET 6.0 (currently 6.0.428)**
- **.NET 5.0 (currently 5.0.408)**
- **.NET 3.1 (currently 3.1.426)**

The "(currently x.y.z)" suffix is the exact SDK patch version installed for that series. We bump these regularly -- see the [API language versions reference](Article: #423) for the authoritative list.

The selected version is on `$PATH` during your build, so `dotnet --version`, `dotnet restore`, `dotnet build`, and `dotnet publish` all work without further configuration.

## End-of-life series

3.1, 5.0, 6.0, and 7.0 are still available for backward compatibility, but Microsoft no longer issues security updates for them. We recommend migrating to 8.0 or above when you're able to.

## Using `global.json` to pin a version from your repo

If your repository has a `global.json` at the root with an `sdk.version` field, the build environment reads it and selects the matching SDK series automatically. This means you don't need to set `DOTNET_VERSION` manually if your repo already pins the version.

```json
{
  "sdk": {
    "version": "8.0.422"
  }
}
```

JSONC is supported, so both `// line comments` and `/* block comments */` in `global.json` are handled correctly, matching Microsoft's spec.

### Resolution order

When more than one version source is present, DeployHQ picks in this order:

1. Explicit `DOTNET_VERSION` environment variable
2. `sdk.version` from `global.json`
3. The default (.NET 10.0)

### What if my pinned version isn't installed?

If your `global.json` pins a series we don't ship (for example, an unreleased version), the build logs a warning and falls back to .NET 10.0 instead of failing with an opaque "SDK not found" error.

### Why `dotnet --version` may not match the pin exactly

We pin the **series** based on your `global.json`, and the build then runs against whichever SDK patch we ship for that series. For example, if your `global.json` says `8.0.100` and we ship `8.0.422`, the build uses `8.0.422`.

This is necessary because the .NET CLI's default `rollForward: latestPatch` policy only rolls forward within the same feature band -- it won't cross feature-band boundaries. The third digit of a .NET 8 patch encodes the feature band: `8.0.100` is in the 1xx band, `8.0.422` is in the 4xx band, so pinning `8.0.100` against an installed `8.0.422` would refuse to run. We resolve this by temporarily moving `global.json` aside (renamed to `global.json.original`) for the duration of the build, then restoring it on completion, so the SDK we ship is the one your build commands actually use.

If you need an exact patch that we don't ship, you can install it yourself from your build commands using Microsoft's `dotnet-install.sh` script.

## Related

- [Configure custom build environments](Article: #283) -- general guide to language version configuration
- [API language versions reference](Article: #423) -- programmatic configuration and the canonical list of installed patches
