Eslam Hamed
Technical Lead & AI Solutions Architect
Building enterprise AI systems, cloud platforms, and production-ready software
.NET 8 and .NET 9 End of Support: Move to .NET 10 Now or Wait for .NET 11?
.NET 8 and .NET 9 both reach end of support on November 10, 2026. That is under four months away, and Microsoft repeated the date in a notice on June 29.
Two things are unusual about this date. An LTS release and an STS release are ending on the same day. And the replacement for both, .NET 10, has been out for months, while .NET 11 is still in preview and due in the same month as the deadline.
If you run production .NET, you have a decision to make and very little slack. My recommendation is to move to .NET 10 now. Here is why, and what I would test on the way.
What end of support means for .NET 8
Your applications keep running on November 11. What stops is patches. Microsoft may ship one final update on November 10 if a critical issue is known, and after that any vulnerability found in the runtime stays unfixed for that version.
For a regulated customer or a public-facing service, an unpatched runtime tends to become an audit finding long before it becomes an incident.
.NET 8 and .NET 9 are already in their final phase. Under Microsoft's policy, the last six months of any release are security-only, so by calculation that phase began in May.
Why .NET 9 ends on the same day
In September 2025 Microsoft extended STS releases from 18 to 24 months. The reason was practical: an out-of-band package should not be able to drag LTS users onto an earlier end date. As a side effect, .NET 9 now finishes alongside .NET 8.
.NET 10 or .NET 11: the support dates line up
| Version | Type | Status on July 15, 2026 | End of support |
|---|---|---|---|
| .NET 8 | LTS | Security-only | November 10, 2026 |
| .NET 9 | STS | Security-only | November 10, 2026 |
| .NET 10 | LTS | Generally available | November 14, 2028 |
| .NET 11 | STS | Preview 6 | November 14, 2028 if it ships by mid-November (my calculation from the 24-month and Patch Tuesday rules) |
Source: .NET support policy, Microsoft's notice.
This changes the usual reasoning. If .NET 11 ships by mid-November as usual, .NET 10 and .NET 11 end on the same day, so the LTS label buys no extra time this cycle. Both will then hop to .NET 12.
So the choice comes down to risk and timing, and there .NET 10 wins clearly:
- It has been generally available and patched for months.
- .NET 11's exact release date is not published, and a November release leaves you days of margin, at best, before .NET 8 stops being patched.
- Nobody serious wants to take a first-week runtime into production because of a deadline.
.NET 11 Preview 6 is interesting. It lists more runtime-async performance work, on top of Preview 4, which compiled the runtime libraries and ASP.NET Core's shared-framework-only libraries with it. .NET 11 has also raised the x86 and x64 hardware baseline to x86-64-v2 since Preview 1, so check any older build agents. Your own code still opts in with a feature switch, and whether that changes by release isn't known yet. None of that justifies waiting.
What can break between .NET 8 and .NET 10
If you skipped .NET 9, you have two breaking-change lists to read. Most items are irrelevant to most apps. These are the ones I would check first, because they fail quietly or only in production.
| Change | Why it can hurt |
|---|---|
| Forwarded headers from unlisted proxies are ignored (since 8.0.17) | Redirect loops and auth failures behind a proxy. A wrong client IP fails no page, so per-IP rate limits and audit logs can go wrong silently. |
| BinaryFormatter always throws (.NET 9) | Old caching and session code fails at runtime, often on one rarely used path. |
| HttpClientFactory defaults to SocketsHttpHandler (.NET 9) | Handler casts and custom configuration may behave differently. |
| BackgroundService runs all of ExecuteAsync as a Task (.NET 10) | Startup ordering can change if you relied on the synchronous part. |
| Runtime drops its default SIGTERM handler (.NET 10) | Typical ASP.NET apps need no action. Verify your shutdown anyway. |
| Default container images move to Ubuntu, with no Debian images (.NET 10) | Native dependencies and apt-based Dockerfiles need review. |
dotnet restore audits transitive packages (projects targeting .NET 10) | Builds with warnings as errors can start failing on NU1901 to NU1904. |
| WebHostBuilder, KnownNetworks and Razor runtime compilation are obsolete (.NET 10) | Warnings first, then work you will have to schedule. |
Two more that catch people:
- Azure Functions in-process model. Support ends on the same date, and it cannot reach .NET 10. Those functions need moving to the isolated worker model, which is a separate project with its own testing.
- Upgrade Assistant. Microsoft's notice still links it, but Learn calls it deprecated and points to the Copilot modernization agent. Check which tool your plan assumes.
How I would prove the upgrade works
A green build tells you the code compiled. Most of the failures above would pass a build and many unit tests. I would treat the runtime upgrade as a release with its own evidence.
The MerlinX platform I work on has a .NET backend, and our release process suits this kind of risk. Releases ship in gated waves. UAT runs the identical image artifacts, verified by digest, not rebuilt look-alikes. Nothing promotes until post-deploy assertions pass and a soak holds against the baseline error rate. A runtime change fits that process well, because the digest proves the thing you tested is the thing you shipped.
For this upgrade I would add some specific checks:
- Client IP behind your proxy. Send a request through the real path and assert the IP in your logs. Nothing else will tell you this is wrong.
- Graceful drain. Stop an instance under load under your real orchestrator, whether systemd or Kubernetes, and confirm in-flight requests finish.
- Base image and native libraries. Rebuild the image and run the paths that use native dependencies.
- Restore in CI. Decide now what your policy is when the transitive audit fires, before it blocks a release at a bad moment.
- Background work. Exercise start-up and shutdown for each hosted service.
- Baseline performance. Measure your own app before and after. Publish no improvement you have not measured yourself.
A timeline that still works
From mid-July, a sensible order is:
- July: inventory every service, its runtime, its container base and any Functions in-process apps. Most teams are surprised by this list.
- August: upgrade low-risk services first and fix the patterns you find, then repeat across the estate.
- September: upgrade the business-critical services through normal release gates.
- October: keep this month free for stragglers and fixes. Avoid planning anything new here.
If that looks tight, it is. November 10 will arrive on schedule, and it will not care about your sprint plan.
My recommendation stands: move to .NET 10, treat it as a release rather than a package bump, and let .NET 11 arrive on its own timeline. You can look at it properly next year, with RTM patches behind it and nothing forcing your hand.
Sources
- Microsoft, .NET 8 and .NET 9 end of support, June 29, 2026
- Microsoft, .NET STS releases supported for 24 months, September 16, 2025
- .NET and .NET Core support policy
- Breaking changes in .NET 9
- Breaking changes in .NET 10
- ASP.NET Core: forwarded headers from unknown proxies
- .NET 10: default container images use Ubuntu
- Azure Functions runtime versions
- Microsoft, .NET 11 Preview 6, July 14, 2026
- .NET 11 Preview 4 release notes, ASP.NET Core
- .NET 11: minimum hardware requirements
- Breaking changes in ASP.NET Core 10
- .NET 10: NuGet audits transitive packages
- .NET Upgrade Assistant overview
Written by Eslam Hamed, a Technical Lead and AI Solutions Architect working on .NET, enterprise AI platforms, and cloud-based software systems.