---
title: ".NET 8 and .NET 9 End of Support (Nov 10, 2026) | Since.dev"
description: ".NET 8 and .NET 9 lose support on November 10, 2026. Where the version hides in your repo, how to move to .NET 10, and what to do if you can't in time."
canonical_url: https://since.dev/guides/dotnet-8-end-of-support
last_updated: 2026-11-04
---

# .NET 8 and .NET 9 end of support: how to move to .NET 10

.NET 8 and .NET 9 both reach end of support on November 10, 2026. After that, Microsoft ships no more patches for either one, security fixes included, so move to .NET 10, the current LTS release, supported until November 14, 2028.

Updated November 4, 2026

## What ends on November 10, 2026

Microsoft's [support policy](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core) lists the same end date for .NET 8 (LTS) and .NET 9 (STS): November 10, 2026. .NET 9 was due to end on May 12, 2026, but Microsoft moved STS releases from 18 to 24 months of support, starting with .NET 9 ([.NET blog](https://devblogs.microsoft.com/dotnet/dotnet-sts-releases-supported-for-24-months/)). That's why both versions go out on the same day.

From the .NET support policy, as of Nov 4, 2026

| Version | Release type | End of support    |
| ------- | ------------ | ----------------- |
| .NET 8  | LTS          | November 10, 2026 |
| .NET 9  | STS          | November 10, 2026 |
| .NET 10 | LTS          | November 14, 2028 |

Here's what end of support means, from Microsoft's [announcement](https://devblogs.microsoft.com/dotnet/dotnet-8-9-end-of-support/): your apps keep running, but there are no more servicing updates, no security fixes and no technical support. November 10 is a Patch Tuesday, and each version may get one last update that day if there's a known critical issue. After that, any new vulnerability stays open on 8 and 9.

This touches a lot of code. About 1.1 million project files on public GitHub still target net8.0 (GitHub's code search count, November 2, 2026, approximate, forks and docs included).

## Where the version hides in your repo

Changing one project file isn't enough. The version is usually pinned in several places, and the one you miss either breaks the build or keeps shipping the old runtime. Check all of these:

Where .NET 8 and .NET 9 are pinned, and what to change

| File or setting                           | Look for                                                                                   | Change to                                     |
| ----------------------------------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------- |
| Every .csproj, plus Directory.Build.props | <TargetFramework>net8.0</TargetFramework>, net9.0, or either one inside <TargetFrameworks> | net10.0                                       |
| global.json                               | An 8.0 or 9.0 SDK under sdk.version                                                        | A 10.0 SDK, such as 10.0.100                  |
| Dockerfiles                               | mcr.microsoft.com/dotnet/sdk:8.0, aspnet:8.0, runtime:8.0                                  | The 10.0 tags                                 |
| GitHub Actions workflows                  | dotnet-version: '8.0.x' on actions/setup-dotnet                                            | '10.0.x', or global-json-file                 |
| Azure App Service on Linux                | linuxFxVersion such as DOTNETCORE\|8.0 in Bicep or ARM                                     | The .NET 10 stack App Service lists for Linux |
| AWS Lambda                                | Runtime: dotnet8 in a SAM template.yaml                                                    | dotnet10                                      |

To find them, run these from the repository root, then open every global.json:

```
git grep -nE "net[89]\.0|dotnet[89]"
git grep -nE "dotnet/[a-z-]+:[89]\.0"
git grep -n "dotnet-version"
```

Lambda keeps its own dates. AWS deprecates the `dotnet8` runtime on November 10, 2026, blocks creating functions on it from July 29, 2027 and blocks updating them from August 31, 2027 ([AWS Lambda runtimes](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)).

## How to move to .NET 10

Go straight from 8 to 10. You don't need to stop at 9, which ends the same day anyway. Microsoft's [upgrade guide](https://learn.microsoft.com/en-us/dotnet/core/install/upgrade) covers the steps below.

1. Install the .NET 10 SDK and update `global.json`. If it still pins an 8.0 SDK, the build either keeps using that SDK or fails to find one. With `rollForward` set to `latestFeature`, the pin stays inside that major version.
2. Change `TargetFramework` to `net10.0` in every project, test projects included, and in `Directory.Build.props` if you set it there.
3. Move packages to the matching major. Set every `Microsoft.AspNetCore.*`, `Microsoft.EntityFrameworkCore.*`, `Microsoft.Extensions.*` and `System.Net.Http.Json` reference to 10.0.0 or later ([ASP.NET Core migration guide](https://learn.microsoft.com/en-us/aspnet/core/migration/90-to-100)). With central package management, they're all in `Directory.Packages.props`. EF Core 10 needs the .NET 10 runtime and won't run on earlier versions ([EF Core docs](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-10.0/whatsnew)), so EF Core and the target framework move together. Update your EF Core database provider to its EF Core 10 release too.
4. Update the Docker images to `sdk:10.0` and `aspnet:10.0`. The default .NET 10 tags are Ubuntu 24.04, not Debian, and Microsoft doesn't ship Debian images for .NET 10 ([Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/core/compatibility/containers/10.0/default-images-use-ubuntu)). If your Dockerfile installs packages with apt or uses a Debian tag such as `8.0-bookworm-slim`, test it on the new base.
5. Update CI. In [actions/setup-dotnet](https://github.com/actions/setup-dotnet), set `dotnet-version` to `'10.0.x'`, or point `global-json-file` at your global.json so CI and your laptop use the same SDK.
6. Update hosting. On Azure App Service for Linux, change `linuxFxVersion` ([App Service docs](https://learn.microsoft.com/en-us/azure/app-service/configure-language-dotnetcore)). On Lambda, change `Runtime` to `dotnet10`. On your own servers, install the .NET 10 runtime before you deploy.
7. Build, run the full test suite, then deploy to staging before production. The SDK reports what needs fixing in code as warnings and errors. Behavior changes only show up in tests.

The edits themselves are small. A project file:

```
<PropertyGroup>
  <TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
```

A multi-stage Dockerfile:

```
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
# build and publish steps unchanged
FROM mcr.microsoft.com/dotnet/aspnet:10.0
```

A GitHub Actions step:

```
- uses: actions/setup-dotnet@v6
  with:
    dotnet-version: '10.0.x'
```

## Breaking changes to check

Read Microsoft's list of [breaking changes in .NET 10](https://learn.microsoft.com/en-us/dotnet/core/compatibility/10.0), plus the separate pages for [ASP.NET Core 10](https://learn.microsoft.com/en-us/aspnet/core/breaking-changes/10/overview) and [EF Core 10](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-10.0/breaking-changes). Coming from .NET 8, read the [.NET 9 list](https://learn.microsoft.com/en-us/dotnet/core/compatibility/9.0) too, since you're skipping it. These are the ones most likely to show up in a typical web app or worker:

- [Restore audits transitive packages](https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/10.0/nugetaudit-transitive-packages). Projects on .NET 10 now get vulnerability warnings for indirect dependencies too. If you treat warnings as errors, restore can fail. Upgrade the package that pulls the vulnerable one in, or add the vulnerable one as a direct reference at a fixed version.
- [System.Linq.AsyncEnumerable is built in](https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/10.0/asyncenumerable). If you reference the community `System.Linq.Async` package, remove it or move to its 7.0.0 release, or you may get ambiguous call errors.
- [BackgroundService runs all of ExecuteAsync as a Task](https://learn.microsoft.com/en-us/dotnet/core/compatibility/extensions/10.0/backgroundservice-executeasync-task). Code before the first `await` no longer blocks other services from starting. If you relied on that ordering, move the work to `StartAsync` or the constructor.
- Default container tags use Ubuntu, as above. Also check any scripts that assume Debian package names.

## If you can't move by November 10

Nothing stops working on November 11. The risk is that the next security fix for .NET won't be released for 8 or 9, and you'll be running code with a known hole. Here's how to keep that window short:

1. Install the latest 8.0 or 9.0 patch now, and the final one if Microsoft ships it on November 10. Rebuild your images so they pick it up.
2. Move internet-facing services first. Internal jobs with no public input can follow.
3. Write down every service still on 8 or 9, who owns its move, and a target date. Review that list every week until it's empty.
4. On Lambda, `dotnet8` functions keep running, and you can still update them until August 31, 2027. AWS may stop applying security patches after deprecation, though ([AWS](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)).
5. On App Service, an outdated runtime is hidden from the portal but apps on it keep running, and the subscription owner gets an email before a runtime is removed from the platform ([App Service docs](https://learn.microsoft.com/en-us/azure/app-service/configure-language-dotnetcore)).

Microsoft's announcement doesn't mention any paid extension for .NET 8 or 9, so plan as if the date is final.

## Where Since.dev fits

Since.dev tracks end-of-life dates like this one from the publisher's schedule. For a repository you scan or connect, it finds the exact file and line that pins .NET 8 or 9, with the days left and the version to move to.

- [Scan any public GitHub repo](https://since.dev/scan.md), no sign-in.
- See every .NET date on the [.NET calendar](https://since.dev/calendar/dotnet.md).
- Your coding agent can ask `check_code` over [MCP](https://since.dev/docs.md#mcp) with a manifest such as a .csproj or global.json, or with the surface `runtime:dotnet@8.0`.
- On Team and up, it opens a fix pull request for supported cases, ready for review. Nothing merges or deploys.

## Questions

### When does .NET 8 support end?

November 10, 2026, the same day as .NET 9. After that date, Microsoft provides no servicing updates, security fixes or technical support for either version.

### Will my .NET 8 app stop working after November 10, 2026?

No. It keeps running. It just stops getting patches, so any vulnerability found after that date stays open until you move to .NET 10.

### Should I move to .NET 9 or .NET 10?

.NET 10. .NET 9 ends support on the same day as .NET 8. .NET 10 is an LTS release, supported until November 14, 2028.

### Can I go straight from .NET 8 to .NET 10?

Yes. Change the target framework to net10.0 and update the SDK, packages, images and CI. Read the breaking change lists for both .NET 9 and .NET 10, since you skip a version.

## Put your code on continuous management.

Scan a public repository now, or give your agent one line.

### See how out of date your code is.

[Scan a repository](https://since.dev/scan.md). Any public GitHub repository. No sign-in.

### Tell your agent what changed since it was trained.

`claude mcp add --transport http since https://api.since.dev/mcp`

---

Every page on this site as Markdown: https://since.dev/sitemap.md. For agents: https://since.dev/llms.txt.
