Contact
EspañolEnglishCatalà

.NET 8 and .NET 9 end of support on 10 November: what happens and how to move to .NET 10

TL;DR: .NET 8 and .NET 9 stop receiving security patches on 10 November 2026. Your applications will still start on the 11th, but any new vulnerability will remain unfixed in those versions. The target is .NET 10, supported until November 2028. .NET Framework 4.8 is not affected, because it follows the Windows lifecycle. In the two applications I've upgraded from .NET 8 and 9 to .NET 10, the change was contained: SDK version, packages, Docker images and the breaking changes that affected each one. One of the easiest to miss is that configuration no longer turns JSON nulls into empty strings.

.NET 8 and .NET 9 end of support on 10 November: what happens and how to move to .NET 10

On 10 November 2026, .NET 8 and .NET 9 stop receiving patches. If you have an API or a web application on either, on the 11th it will still start as if nothing had happened. And that’s exactly why it’s easy to put off.

Over the last year I’ve moved two production applications to .NET 10: E3M, EPMTIC’s ERP, from .NET 8, and Power Time, from .NET 9. Here’s what end of support means, what changed in those upgrades and the steps I’d follow if I had to do it this week.

What “end of support” means (and what it doesn’t)

According to Microsoft’s announcement, from 10 November there will be no more servicing updates, security fixes or technical support for .NET 8 or .NET 9. Both may get one last update that same day if there’s a known critical issue. After that, it’s over.

Your application doesn’t shut down. What happens is quieter: when the next runtime or ASP.NET Core vulnerability is published, the patch will ship for the supported versions and not for yours. If the application is exposed to the internet, that gap stays open.

Two clarifications:

  • .NET 9 ends at the same time as .NET 8 because Microsoft extended support for STS releases from 18 to 24 months. It was due to end in May and moved to November.
  • .NET Framework 4.8 isn’t on this list. It’s supported as part of Windows. If your application is Web Forms or WinForms on .NET Framework, your problem is a different one (I cover it at the end), but it has no 10 November deadline.

And if you’re still on .NET 6, you’ve been without patches since November 2024.

The target is .NET 10, which is LTS and supported until 14 November 2028.

How two real upgrades went

Power Time, from .NET 9 to .NET 10. The change fitted in one commit touching 18 files. Most of it was project-level: bumping the version, updating packages and changing the Docker images. I took the chance to centralize package versions in a Directory.Packages.props, which is what touched the most files. In code there were three small adjustments: the OpenAPI security scheme transformer, the name of a forwarded-headers property (KnownNetworks becomes KnownIPNetworks) and credential creation in the push notification service, because its package was updated.

E3M, from .NET 8 to .NET 10. Two things here are worth telling.

The first has to do with configuration. In .NET 10, the JSON configuration provider no longer turns null into empty strings: they now arrive as null and are bound as such. A key set to null in an appsettings.json that the code treats as “empty, use the default” becomes null. E3M had no null in its configuration, but the code assumed those keys existed. Before deploying, I added a startup validation of the required keys, with a message that says exactly which one is missing.

The second: the upgrade surfaced debt that was already there. Three fields were NOT NULL in the database, but the Entity Framework model saw them as optional. It wasn’t a .NET 10 problem; it had been like that for a while and nobody had noticed. It was caught by dotnet ef migrations has-pending-model-changes, which I ran before and after the version bump. Better on your machine than in production.

Swashbuckle 10’s security API also changed: if you declare the security requirement with AddSecurityRequirement, you have to adapt it to OpenApiSecuritySchemeReference and the new Microsoft.OpenApi namespace.

The steps, in order

This is how I’d do it today with an ASP.NET Core application on .NET 8 or 9.

1. Pin the SDK. A global.json at the root stops each machine or pipeline from building with a different SDK:

{
  "sdk": {
    "version": "10.0.100",
    "rollForward": "latestFeature"
  }
}

2. Change the target framework in each project (or once in Directory.Build.props if you have one):

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

3. Update the Microsoft packages (Microsoft.AspNetCore.*, Microsoft.EntityFrameworkCore.*, Microsoft.Extensions.*) to version 10 and review third-party ones. Swashbuckle, for example, has its own changes in version 10.

4. Change the Docker images:

FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
# ...
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime

5. Validate configuration at startup. It’s the defence against the null change, and it’s worth it even if you don’t upgrade:

using System.ComponentModel.DataAnnotations;

public sealed class JwtOptions
{
    [Required] public string Key { get; set; } = "";
    [Required] public string Issuer { get; set; } = "";
    [Required] public string Audience { get; set; } = "";
}

builder.Services.AddOptions<JwtOptions>()
    .Bind(builder.Configuration.GetSection("Jwt"))
    .ValidateDataAnnotations()
    .ValidateOnStart();

If a key is missing, or arrives as null or empty, the application fails at startup with an error naming the property, instead of failing on the first request that uses it.

6. Check the data model. If you use Entity Framework Core (with the dotnet-ef tool and the Microsoft.EntityFrameworkCore.Design package), this command tells you whether the model and the migrations are out of sync, which is exactly what I found in E3M. Run it once per DbContext:

dotnet ef migrations has-pending-model-changes --context MyDbContext

7. Read the breaking-change lists for .NET 9 (if you’re coming from .NET 8) and .NET 10, filtering by what you use. Then run the tests and deploy to a test environment first.

A note on tools: Microsoft has marked the .NET Upgrade Assistant as deprecated and recommends the GitHub Copilot modernization agent instead. For a jump from .NET 8 to .NET 10 with a good test suite, in my experience you don’t need a dedicated migration assistant: the change is manageable and understanding each adjustment pays off.

If yours is .NET Framework

If your application is on .NET Framework 4.8 (or 4.6.2 or later; earlier versions are already out of support), you don’t have the 10 November urgency, but the jump is a different one. Web Forms doesn’t exist in modern .NET, so it isn’t a version bump: the web layer has to be rebuilt while preserving the business logic. That’s what I do in .NET application modernization, and I explain the strategy (all at once or in stages) in modernizing a legacy ERP.

What I’d do this week

Open a terminal in the folder where you keep your repositories and find which version each project uses:

grep -r --include='*.csproj' --include='Directory.Build.props' "<TargetFramework" .

If you see net8.0, net9.0 or, worse, net6.0 in anything in production, you know what needs planning. If there are many applications, or you don’t have tests you can trust, start with a technical audit: in one week it tells you what’s there, what breaks when you upgrade and in what order to do it.

Resources

Frequently asked questions

Will my .NET 8 application stop working on 10 November?

No. It will keep starting and running as before. What stops arriving are the patches: any vulnerability published after that date won't be fixed in .NET 8 or .NET 9.

Why does .NET 9 lose support on the same day as .NET 8?

Because Microsoft extended support for STS releases (the odd-numbered ones) from 18 to 24 months starting with .NET 9. That moved its end of support from May to November 2026, the same day as .NET 8.

Does it affect .NET Framework 4.8 applications?

No. .NET Framework 4.8 is supported as a Windows component and follows its lifecycle. Its problem is a different one: it gets no new features and many libraries no longer support it, but it doesn't have this deadline.

Which version should I upgrade to?

To .NET 10, which is LTS and supported until 14 November 2028. You can jump straight from .NET 8 to .NET 10 without going through .NET 9, but you should also review the .NET 9 breaking changes, because you get them anyway.