Skip to content

    Back to articles

    5 min read

    Separate the .NET support deadline from .NET 11 adoption

    Updated

    The deadline is a support decision

    On November 10, 2026, both .NET 8 and .NET 9 reach end of support. .NET 11 is currently a release candidate, with Microsoft’s launch event scheduled for November 10–13. That timing can make it tempting to wait and move straight to the newest release. I would not make the support deadline depend on that choice.

    There are two separate questions: how will a service remain on a supported .NET version after its current version expires, and when does it make sense to adopt .NET 11? The first has a fixed date. The second is a platform decision that should account for compatibility, dependencies, operational readiness and the team’s appetite for change.

    .NET 10 is already a released LTS version, and Microsoft lists its support through November 14, 2028 (support policy). That makes it a practical target for teams that need a supported landing place now. Moving to it does not prevent a later move to .NET 11. It gives that later decision its own schedule instead of turning an approaching support date into a reason to rush onto a new major release.

    Make the inventory useful

    I would start with an inventory of deployable applications, not just a list of repositories. A repository can contain several services, workers, scheduled jobs or applications with different release and runtime requirements. The inventory should let someone answer, for each production workload:

    • What target framework and runtime does it use?
    • Where does it run, and how is it deployed?
    • Which libraries, SDKs, hosting components and external integrations does it depend on?
    • Who owns its code and can validate it in a production-like environment?
    • What operational or business process would be affected if the upgrade exposed a problem?

    The point is not to build a perfect catalogue before taking action. It is to find work that a framework-version report alone will miss: a service whose dependency has no compatible release, a background process nobody remembers to test, or a deployment image that still carries an old runtime. Dependencies include more than NuGet packages. Build agents, container base images, runtime installations, database providers and other services in the call path can all be part of the upgrade surface.

    I would record uncertainty rather than mark it as resolved. “Owner unknown” and “integration not tested” are useful inventory findings; they are not reasons to quietly assume the migration will be simple. If several services share a library or build pipeline, record that relationship too. It can reveal a single fix that unblocks multiple applications, or a shared change whose failure would affect many of them.

    Prioritize by risk, not by repository order

    Once the inventory exists, I would sort by risk and readiness rather than upgrade every application alphabetically. A useful first pass considers the consequence of staying on an unsupported version, the complexity of the application’s dependencies, how much of its behavior can be exercised automatically, and whether someone can verify the result.

    A service with a straightforward build, well-understood dependencies and a reliable test path may be a good early migration. That does not mean it is the most important service; it means it can test the path the rest of the work will use. A high-impact service with a difficult integration boundary may deserve an early assessment, but not necessarily the first production deployment. Separating assessment from rollout helps expose the hard work before the calendar is tight.

    I would also identify blockers explicitly: packages without a compatible version, platform-specific behavior, outdated deployment images, missing test coverage or an unavailable service owner. Then assign each blocker an action and a person responsible. “Upgrade all services” is a goal, not a plan. A list of services, known risks and decisions needed is something a team can actually manage.

    Test on .NET 10, then decide about .NET 11

    For production services still on .NET 8 or .NET 9, I would create a migration branch targeting .NET 10 and use it to learn what the upgrade requires. Build and restore first, then investigate compiler and dependency warnings rather than suppressing them to get a green build. Review the documented .NET 10 breaking changes, and test the behaviors that matter to the service: startup, configuration, authentication, database access, messaging, background work, health checks and deployment.

    A successful compile is only an early signal. I would run the application’s automated tests, exercise its key integration paths, and validate its deployment using the same kind of environment and release process used in production. If a workload has no adequate tests, I would identify a small set of high-value checks before treating the framework change as safe to ship. That work is part of the migration, not optional polish.

    After the service is on .NET 10, decide separately whether and when to adopt .NET 11. That choice can be based on actual compatibility findings and operational needs, rather than an assumption that the newest version must be the deadline target. A team that has completed a supported move can evaluate .NET 11 on a deliberate schedule; a team that waits for its release before beginning has coupled two changes and left less room to find problems.

    The useful milestone is not “everyone is on the newest .NET.” It is that every production service has a supported runtime and a tested route to get there. Meet that milestone on its own schedule, then choose the next platform version on its merits.

    Drafted with AI assistance, reviewed and edited by Ali.