dotnet / dotnet/aspnetcore

ANCM ignores 10.0.105 Site Extension, falls back to incompatible 10.0.103 native runtime (SDK 10.0.201)

Open
#66,203 10 comments 0 reactions 0 assignees View on GitHub
area-networking Regression
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

# SDK 10.0.201 changes UseCurrentRuntimeIdentifier default, producing architecture-locked output that breaks Azure App Service deployment

## Description

Upgrading from .NET SDK 10.0.100 (feature band 1) to 10.0.201 (feature band 2) introduces two breaking behavioral changes that caused a full day of production deployment debugging:

1. **`UseCurrentRuntimeIdentifier` now defaults to `true`** — AnyCPU projects built with a 64-bit SDK produce x64-only output instead of architecture-neutral IL. This breaks deployment to 32-bit Azure App Service app pools and any environment where the target bitness differs from the build machine.

2. **Runtime targeting incompatibility** — Apps built with SDK 10.0.201 require a runtime version newer than what Azure App Service provides natively (10.0.103). The installed Site Extension (10.0.105) is ignored by ANCM, which falls back to the native 10.0.103 runtime, causing an ANCM startup failure.

## Reproduction Steps

1. Create a standard ASP.NET Core web app with no explicit `PlatformTarget`, `RuntimeIdentifier`, or `Prefer32Bit` — default AnyCPU configuration
2. Build and publish with SDK 10.0.100 on a 64-bit machine
3. Verify with `corflags` that output is: `PE32, ILONLY=1, 32BITREQ=0, 32BITPREF=0` (true AnyCPU)
4. Build and publish the **same project** (no code changes) with SDK 10.0.201 on the same 64-bit machine
5. Verify with `corflags` that output is now architecture-specific (x64)
6. Deploy the 10.0.201-built app to Azure App Service with a 32-bit app pool
7. Observe: Application fails to start

Additionally:
8. Azure App Service has native runtime 10.0.103
9. Install Site Extension for runtime 10.0.105
10. ANCM ignores the Site Extension and falls back to native 10.0.103
11. 10.0.103 cannot run the 10.0.201-built app → ANCM startup error

## Expected behavior

- SDK feature band upgrades (10.0.1xx → 10.0.2xx) should not silently change the default output architecture of AnyCPU projects
- `UseCurrentRuntimeIdentifier` should default to `false` for non-self-contained/framework-dependent builds, preserving architecture-neutral output that runs on both 32-bit and 64-bit hosts
- Apps built with SDK 10.0.201 should be runnable on the 10.0.103 runtime (same major.minor), or at minimum ANCM should correctly discover and use the Site Extension runtime (10.0.105) before falling back to the native runtime

## Actual behavior

1. `UseCurrentRuntimeIdentifier` silently defaults to `true` in 10.0.2xx, locking publish output to the SDK's own architecture (x64). The deployment zip only contains 64-bit assets, failing on 32-bit targets.

2. ANCM ignores the installed 10.0.105 Site Extension and falls back to native 10.0.103 runtime, which cannot run the 10.0.201-built app, producing an ANCM startup error (HTTP 500.31 or similar).

## Regression?

Yes. Same project builds correctly with SDK 10.0.100, producing true AnyCPU output. The behavioral change is introduced in feature band 2 (10.0.2xx) with no documented breaking change notice.

## Known Workarounds

**Workaround 1** — Add to `Directory.Build.props`:
```xml

false

```

**Workaround 2** — Pin SDK in `global.json` to feature band 1:
```json
{
"sdk": {
"version": "10.0.100",
"rollForward": "disable"
}
}
```

We are currently using both: `global.json` pin ensures the build targets a runtime compatible with what Azure has installed (10.0.103), and `UseCurrentRuntimeIdentifier=false` is kept as a safety net for when we eventually move to 10.0.2xx.

## Verified publish output (SDK 10.0.201 + UseCurrentRuntimeIdentifier=false)

| Asset | Result |
|---|---|
| Main DLL corflags | PE32, ILONLY=1, 32BITREQ=0, 32BITPREF=0 (true AnyCPU) |
| SkiaSharp runtimes | Present for win-x86, win-x64, win-arm64 |

This confirms the workaround restores correct behavior — both architectures' native dependencies are included and the main assembly is architecture-neutral.

## Configuration

- **SDK (working):** 10.0.100
- **SDK (broken):** 10.0.201
- **Target framework:** net10.0
- **Build agent:** `windows-latest` (Azure Pipelines), 64-bit SDK
- **Hosting model:** InProcess (`InProcess`)
- **Azure App Service:** Windows, 32-bit app pool
- **Native runtime on Azure:** 10.0.103
- **Site Extension installed:** 10.0.105
- **Project configuration:** No explicit `PlatformTarget`, `RuntimeIdentifier`, or `Prefer32Bit` — default AnyCPU
- **OS:** Windows (build agent and deployment target)

## Impact

- **Breaking change** with no mention in 10.0.2xx release notes (that we could find)
- Particularly impactful for **Azure App Service users** where runtime versions lag behind SDK releases
- The combination of architecture change + ANCM Site Extension discovery failure creates a **double failure** that is extremely difficult to diagnose
- A feature band bump (the hundreds digit) is not where users expect breaking behavioral changes to default build output
- Cost us a **full day of production debugging** across two engineers

## Suggestions

1. `UseCurrentRuntimeIdentifier` should default to `false` for framework-dependent deployments (the common case)
2. If this is an intentional change, it needs **prominent documentation** in the 10.0.2xx release notes and a migration guide
3. ANCM should reliably use installed Site Extensions before falling back to the native runtime
4. Consider adding a build warning when `UseCurrentRuntimeIdentifier` changes from a previous build's behavior (similar to how TFM changes produce warnings)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.