BYBOWU > Blog > Web development

Azure App Service and .NET 10 LTS: What to Fix Now

blog hero image
.NET 10 LTS is out, but many teams hit snags rolling it onto Azure App Service—“Preview” runtimes lingering in some regions, CI/CD pinning old SDKs, and a recent Kestrel CVE to double‑check. Here’s a practical, field-tested playbook to get production-ready fast: align your hosting stack, choose the right deployment model (framework-dependent, self-contained, or container), verify the patch level, and run a focused seven‑day rollout. If you own revenue-bearing APIs or portals, this...
📅
Published
Nov 20, 2025
🏷️
Category
Web development
⏱️
Read Time
11 min

.NET 10 LTS is here, and it’s the release most production teams have been waiting for. It’s fully supported for three years (through November 2028), and it lands alongside C# 14 plus a long list of ASP.NET Core and runtime performance upgrades. But here’s the thing: if you’re deploying to Azure App Service this week, you may still see a “Preview” label in some regions or hit a runtime mismatch between your build agents and the platform image. This guide shows you exactly how to roll out .NET 10 LTS safely, avoid the common faceplants, and capitalize on the gains quickly.

Illustration of an Azure-like deployment pipeline highlighting mixed runtime statuses

What changed this week—and why it matters

.NET 10 is a Long-Term Support release, which means three years of patches, predictable monthly servicing, and a stable base for enterprise roadmaps. It brings tangible performance work in the JIT, NativeAOT improvements, memory pool eviction in ASP.NET Core, and passkey (WebAuthn/FIDO2) support in Identity. C# 14 adds extension members, field-backed properties, and span-friendly conversions that reduce ceremony and open the door to framework-level optimizations. For teams maintaining customer-facing portals and APIs, that translates to faster cold starts, fewer allocations under load, and simpler code in hotspots.

On the hosting side, Azure App Service has published .NET 10 across Windows and Linux plans, but rollouts happen in waves. It’s normal to see a “Preview” tag linger in specific regions for a short window after GA while images propagate and platform validation completes. Practically, that can mean a Kudu console showing one runtime revision while your app expects another. If your last deploy failed with a 500.31 (ANCM failed to find native dependencies) or your portal only lists “.NET 10 (LTS) (Preview),” you’re looking at platform drift—not your code.

Is .NET 10 LTS safe to deploy on Azure App Service today?

Yes—with guardrails. The primary risks early in the rollout are:

  • Runtime mismatch: Your app was built against the GA .NET 10 SDK, while the site runs an older or RC image in a given region.
  • Unpinned CI/CD: Older agents or global.json point to 9.x/8.x SDKs, producing binaries your App Service slot doesn’t expect.
  • Security patch level: A recent Kestrel request-smuggling CVE required patches in 8/9 and landed prior to 10 GA. You want assurance your stack includes those fixes.

All of these are solvable. The key is to align the build toolchain and the site’s runtime, verify the patch level, and choose a deployment model that gives you control while regions catch up.

The Runtime Alignment Checklist (use this before you hit Deploy)

Copy this into your release ticket and close each item deliberately:

  1. Lock your target: Confirm you’re moving to .NET 10 LTS for the three-year support window. Note your support horizon so product and infosec are aligned (through mid‑November 2028). Document it in your architecture repo.
  2. Pin the SDK in source: Add or update global.json with your chosen 10.0.x SDK. In CI, explicitly install that SDK step (don’t rely on “latest”). Run dotnet --info during builds and publish the output as an artifact so ops can verify.
  3. Decide your deployment model per app:
    • Framework-dependent on App Service stack: simplest when the region’s runtime matches GA. Good default once rollouts stabilize.
    • Self-contained (SCD): includes the runtime with your app. Larger package; removes reliance on the site’s installed runtime. Use when a region lags or you need strict binary parity.
    • Container: full control over image, runtime, and native deps. Strongest isolation; recommended for critical workloads or multi-region fleets during staggered rollouts.
  4. Verify the site’s runtime image: Use the Kudu console or Environment page to check the actual runtime. On Linux, inspect dotnet --info inside the container/SSH session. On Windows, confirm the ASP.NET Core Hosting Bundle version via diagnostics. If you see RC bits but need GA, choose SCD or container for this release.
  5. Confirm the Kestrel patch (CVE-2025-55315): Ensure your platform or image includes the fixed versions. The patch landed before GA; the GA runtime carries the fix. If you’re staying on 8/9 anywhere, upgrade to patched 8.0.21/9.0.10 or later. If you run custom Kestrel packages (2.x), update to the patched package and redeploy.
  6. Upgrade the tooling chain: Use a .NET 10-capable IDE/agent (Visual Studio 2026 or updated editors/SDKs). Make sure your container base images or build agents aren’t pulling older 9.x manifests by default.
  7. TLS and HTTP mode sanity check: If you terminate TLS at the App Service front end and forward HTTP/1.1 to Kestrel, review your reverse proxy headers and keep-alive settings. If you use HTTP/2 or WebSockets, run smoke tests with load and long-lived connections.
  8. Observability ready: Turn on request logging and app metrics before the swap. If you adopted the new memory pool eviction, monitor working set and GC pause times to validate improvements under your traffic shape.
  9. Rollback plan: Keep the previous slot warm on .NET 9 or your last known good image. Validate that connection strings and identity secrets remain compatible in both directions.

If you need a broader program plan beyond the technical checklist, our 30‑day .NET 10 LTS rollout plan maps cross‑team milestones, approvals, and risk gates. For production hardening specifics, see the .NET 10 LTS production upgrade playbook.

Let’s get practical: deployment choices that actually work

1) When to prefer framework-dependent on App Service

Once your target region shows the GA runtime and your smoke tests pass, go framework-dependent. It keeps packages lean and lets App Service take monthly patch updates. Set up alerts on the slot for runtime changes so you’re not surprised by servicing revs.

2) When to ship self-contained

If your region still shows a preview tag or you’re mid-incident and can’t move regions, publish self-contained for this release. Yes, the artifact is larger, but parity beats guesswork. Revert to framework-dependent when the region catches up.

3) Containerize strategic services

For revenue-bearing APIs, containers give you deterministic control: you pick the .NET 10 base image, the exact ASP.NET Core bundle, and any native libs. This also neutralizes “surprise” image updates on the platform. If you run across clouds, images make parity easy.

What’s actually new for your app in .NET 10

This is the part product managers love: you’re not just buying time—you’re buying speed and capability. A few highlights we’ve validated in real projects:

  • Lower memory under load: Automatic memory pool eviction reduces long‑tail working set growth in busy web apps. Track working set and GC pauses before/after; you’ll often see flatter lines on peak days.
  • Faster hot paths: JIT inlining and devirtualization help tight loops, JSON, and text-heavy code. Combine with C# 14’s span-friendly conversions to trim allocations in parsers and formatters.
  • Passkeys built-in: ASP.NET Core Identity supports WebAuthn/FIDO2. If your auth backlog includes “kill password resets,” this is where you start piloting.
  • Cleaner code: Extension members and field-backed properties remove ceremony in core domains and library code. Less boilerplate reduces bug surface and improves readability for code reviews.

If you’re also modernizing your front end, pair this upgrade with the infra work you planned for server-side caching and proxying in frameworks like Next.js. We’ve written about sane defaults for those moves in our Next.js 16 migration playbook.

But there’s a catch: platform drift is real

Early-adopter week always exposes drift: GA runtimes in dev, RC images in one prod region, an older SDK on the mac mini under a designer’s desk. Your goal is to remove ambiguity.

Three field tips:

  • Make the versions visible. Surface dotnet --info and the ASP.NET Core shared framework version in your health endpoint. During a staggered rollout, this saves hours.
  • Stamp your builds. Embed the SDK version and git SHA in assembly metadata and response headers for internal routes. When a slot misbehaves, you’ll know exactly which bits you’re running.
  • Choose a strong default. For critical services, default to containers until your regions converge on GA. Move back to framework-dependent when the blast radius is low.

People also ask

Do we have to move now, or can we stay on .NET 9?

You can stay on .NET 9 for a while, but the clock is ticking. Standard-term releases have a shorter runway, and security posture gets harder to defend the longer you straddle versions. If you have budget and talent this quarter, moving to .NET 10 LTS reduces 2026 upgrade risk.

Does .NET 10 LTS include the Kestrel fix?

Yes—the request-smuggling fix landed prior to GA and is included in the .NET 10 line. If you run any 8/9 services in parallel, make sure those environments are on patched versions.

Do we need Visual Studio 2026 to ship?

No, but you do need .NET 10-capable tooling. Many teams ship via CI with the 10.x SDK and use VS Code or fleet-managed build agents. If you’re all-in on Visual Studio, upgrade to the supported release that tracks .NET 10.

Linux or Windows on App Service?

Pick the one your ops team can observe and patch confidently. Linux plans pair nicely with containers and keep image parity straightforward. Windows plans are fine if you have IIS modules, legacy components, or org standards. Either way, verify the runtime version before swapping.

A focused seven‑day rollout plan

If you already ran pilot tests on RC builds, you can move fast. Here’s a pragmatic schedule we’ve used with mid‑size product teams:

  • Day 1: Lock the SDK (global.json), bump analyzers, and fix breaking build warnings. Produce a signed RC build and capture dotnet --info in artifacts.
  • Day 2: Spin up a greenfield App Service in your primary region. If runtime shows GA, test framework-dependent first; else publish self-contained. Exercise auth, file uploads, and your largest JSON payloads.
  • Day 3: Load test to 2× your 95th percentile traffic. Monitor working set and GC; capture deltas versus last month’s baseline.
  • Day 4: Enable passkeys in a non-admin tenant if you plan passwordless. Confirm recovery paths and device enrollment flows.
  • Day 5: Harden logging and metrics, add runtime/version stamps to health endpoints, and preflight swap scripts.
  • Day 6: Regional canary: route 5–10% of traffic via slot swap or Front Door rules. Watch for 500.31 or cold-start regressions.
  • Day 7: Full swap. Keep the previous slot warm for 48–72 hours. Schedule a post-mortem even if everything went smoothly; lock in the playbook for the next service.

If you want the broader program template—with stakeholder comms and risk approvals—use our 30‑day .NET 10 LTS plan and adapt it to your governance model.

Common gotchas and edge cases

  • 500.31 on swap: You published framework-dependent, but the slot runs an RC runtime. Either move to SCD for this release or containerize that service.
  • Native image or libgdiplus surprises: If you use image processing or PDF generation, confirm native dependencies in your container or ensure the App Service image has the required libraries.
  • Sticky sessions: If you rely on in‑memory session in a multi-instance plan, expect different GC and eviction behavior. Validate with real load; consider distributed session stores.
  • Auth cookies + passkeys: Audit cookie flags and SameSite behavior when introducing passkeys. Test across iOS/Android and major browsers.

What to do next

  • Run the Runtime Alignment Checklist on your top three web apps.
  • Pick a deployment model per app (framework-dependent, SCD, or container) and document the why.
  • Verify the Kestrel patch level everywhere, especially in older services you’re keeping through Q1.
  • Schedule a seven‑day rollout for one canary service next week.
  • If you want expert help, our team offers full‑stack upgrade services with fixed‑scope packages. You can also just talk to us for a quick second opinion.
Isometric illustration of a runtime alignment checklist with servers and containers

Zooming out

.NET 10 LTS isn’t just a checkbox upgrade. It’s a performance, reliability, and security step that pays back over the next three years—if you treat rollout as an engineering activity, not a toggle in the portal. Align the runtime, lock the SDK, verify the patch level, and pick the deployment model that matches your risk tolerance this week. You’ll earn happier pages from on-call, faster endpoints for customers, and a roadmap that doesn’t hinge on scramble-upgrades next spring.

Want a deeper migration sequence end‑to‑end? Start with our production upgrade playbook, then tailor the steps to your architecture and compliance obligations.

Photo of a modern server corridor with blue lighting
Written by Viktoria Sulzhyk · BYBOWU
4,126 views

Get in Touch

Ready to start your next project? Let's discuss how we can help bring your vision to life

Email Us

[email protected]

We'll respond within 24 hours

Call Us

+1 (602) 748-9530

Available Mon-Fri, 9AM-6PM

Live Chat

Start a conversation

Get instant answers

Visit Us

Phoenix, AZ / Spain / Ukraine

Digital Innovation Hub

Send us a message

Tell us about your project and we'll get back to you

💻
🎯
🚀
💎
🔥