references/aspnetcore-dotnet10to11.md
# ASP.NET Core Breaking Changes (.NET 11)
These breaking changes affect ASP.NET Core projects. Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/11
> **Note:** .NET 11 is in preview. Additional ASP.NET Core breaking changes are expected in later previews.
## Source-Incompatible Changes
### Microsoft.OpenApi updated to v3 with OpenAPI 3.2.0 support (Preview 2)
**Impact: Medium.** `Microsoft.AspNetCore.OpenApi` updated its dependency from `Microsoft.OpenApi` 2.x to 3.x, adding OpenAPI 3.2.0 document generation. The underlying `Microsoft.OpenApi` library has breaking API changes in the v2→v3 transition.
Code that directly uses `Microsoft.OpenApi` types (`OpenApiDocument`, `OpenApiSchema`, `OpenApiOperation`, etc.) will have compile errors.
**Fix:** Follow the [Microsoft.OpenApi v3 upgrade guide](https://github.com/microsoft/OpenAPI.NET/blob/main/docs/upgrade-guide-3.md). If you only use the ASP.NET Core OpenAPI integration (`.WithOpenApi()`, `MapOpenApi()`) without touching the object model directly, no changes are needed.
Source: https://github.com/dotnet/aspnetcore/pull/65415
## Behavioral Changes
### Blazor Virtualize<T> default OverscanCount changed from 3 to 15 (Preview 3)
**Impact: Low.** The default `OverscanCount` on the `Virtualize<TItem>` component changed from `3` to `15` to support variable-height item measurement. `QuickGrid` retains its own default of `3`.
**Fix:** If performance-sensitive, set `OverscanCount` explicitly: `<Virtualize OverscanCount="3" />`.
Source: https://github.com/dotnet/aspnetcore/pull/64964
references/core-libraries-dotnet10to11.md
# Core .NET Libraries Breaking Changes (.NET 11)
These breaking changes affect all .NET 11 projects regardless of application type. Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/11
> **Note:** .NET 11 is in preview. Additional breaking changes are expected in later previews.
## Obsoleted APIs
### NamedPipeClientStream constructor with `isConnected` parameter obsoleted (SYSLIB0063)
**Impact: High (for projects using `TreatWarningsAsErrors`).** The `NamedPipeClientStream` constructor overload that accepts a `bool isConnected` parameter has been obsoleted. The `isConnected` argument never had any effect — pipes created from an existing `SafePipeHandle` are always connected. A new constructor without the parameter has been added.
```csharp
// .NET 10: compiles without warning
var pipe = new NamedPipeClientStream(PipeDirection.InOut, isAsync: true, isConnected: true, safePipeHandle);
// .NET 11: SYSLIB0063 warning (error with TreatWarningsAsErrors)
// Fix: remove the isConnected parameter
var pipe = new NamedPipeClientStream(PipeDirection.InOut, isAsync: true, safePipeHandle);
```
**Fix:** Remove the `isConnected` argument and use the new 3-parameter constructor `NamedPipeClientStream(PipeDirection, bool isAsync, SafePipeHandle)`.
Source: https://github.com/dotnet/runtime/pull/120328
## Behavioral Changes
### DeflateStream and GZipStream write headers and footers for empty payloads
**Impact: Medium.** `DeflateStream` and `GZipStream` now always write format headers and footers to the output stream, even when no data is written. Previously, these streams produced no output for empty payloads.
This ensures the output is a valid compressed stream per the Deflate and GZip specifications, but code that checks for zero-length output will need updating.
```csharp
// .NET 10: output stream is empty (0 bytes)
// .NET 11: output stream contains valid headers/footers
using var ms = new MemoryStream();
using (var gz = new GZipStream(ms, CompressionMode.Compress, leaveOpen: true))
{
// write nothing
}
// ms.Length was 0 in .NET 10, now > 0 in .NET 11
```
**Fix:** If your code checks for empty output to detect "no data was compressed," check the uncompressed byte count instead, or adjust the length check to account for headers/footers.
Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/11/deflatestream-gzipstream-empty-payload
### MemoryStream maximum capacity updated and exception behavior changed
**Impact: Medium.** The maximum capacity of `MemoryStream` has been updated and the exception behavior for exceeding capacity has changed.
**Fix:** Review code that creates very large `MemoryStream` instances or catches specific exception types related to capacity limits.
Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/11/memorystream-max-capacity
### TAR-reading APIs verify header checksums when reading
**Impact: Medium.** TAR-reading APIs now verify header checksums during reading. Previously, invalid checksums were silently ignored.
```csharp
// .NET 11: throws if TAR header checksum is invalid
using var reader = new TarReader(stream);
var entry = reader.GetNextEntry(); // may throw for corrupted files
```
**Fix:** Ensure TAR files have valid checksums. If processing hand-crafted or legacy TAR files, add error handling for checksum validation failures.
Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/11/tar-checksum-validation
### ZipArchive.CreateAsync eagerly loads ZIP archive entries
**Impact: Low.** `ZipArchive.CreateAsync` now eagerly loads ZIP archive entries instead of lazy loading. This may affect memory usage for very large archives.
Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/11/ziparchive-createasync-eager-load
### Environment.TickCount made consistent with Windows timeout behavior
**Impact: Low.** `Environment.TickCount` behavior has been made consistent with Windows timeout behavior. Code that relies on specific tick count wrapping or comparison patterns may need adjustment.
Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/11/environment-tickcount-windows-behavior
### Globalization: Japanese Calendar minimum supported date corrected
**Impact: Low.** The minimum supported date for the Japanese Calendar has been corrected. Code using very early dates in the Japanese Calendar may be affected.
Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/globalization/11/japanese-calendar-min-date
### ZipArchive now validates CRC32 when reading entries (Preview 3)
**Impact: Low–Medium.** ZIP archive reads now validate the CRC32 checksum of each entry. Previously, corrupt or truncated archives were silently accepted; they now throw `InvalidDataException`.
**Fix:** Ensure ZIP files are not corrupted. If processing partially-written or legacy archives, add error handling for `InvalidDataException`.
Source: https://github.com/dotnet/runtime/pull/124766
### Unhandled BackgroundService exceptions now stop the host (Preview 3)
**Impact: Medium.** Unhandled exceptions thrown from `BackgroundService.ExecuteAsync()` now propagate and stop the host application. Previously they were silently swallowed.
```csharp
// .NET 10: exception silently swallowed, host continues
// .NET 11: exception propagates, host stops
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
throw new InvalidOperationException("oops"); // now kills the host
}
// FIX: Add proper exception handling
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
// ... work ...
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
_logger.LogError(ex, "Background service failed");
}
}
```
**Fix:** Add try/catch in `ExecuteAsync()` for any `BackgroundService` that should not crash the host on failure.
Source: https://github.com/dotnet/runtime/pull/124863
### TarWriter emits HardLink entries for hard-linked files (Preview 3)
**Impact: Low.** When `TarWriter` archives a directory containing hard links, the same inode encountered more than once is now written as a `HardLink` entry pointing back to the first occurrence, rather than duplicating the file data.
**Fix:** If consuming tar archives produced by .NET code, ensure the reader handles `HardLink` entry types.
Source: https://github.com/dotnet/runtime/pull/123874
### Zstandard APIs moved from preview package to System.IO.Compression (Preview 3)
**Impact: Low.** `ZstandardStream` and related APIs that were previously in the `System.IO.Compression.Zstandard` preview NuGet package are now in-box in `System.IO.Compression`.
**Fix:** Remove the `<PackageReference Include="System.IO.Compression.Zstandard" />` preview package if present. The APIs are now available without any additional package reference.
Source: https://github.com/dotnet/runtime/pull/114545
references/cryptography-dotnet10to11.md
# Cryptography Breaking Changes (.NET 11)
These breaking changes affect projects using cryptography APIs. Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/11
> **Note:** .NET 11 is in preview. Additional cryptography breaking changes are expected in later previews.
## Behavioral Changes
### DSA removed from macOS
**Impact: Medium (macOS only).** DSA (Digital Signature Algorithm) has been removed from macOS. Code that uses DSA for signing or verification will throw on macOS.
```csharp
// BREAKS on macOS in .NET 11
using var dsa = DSA.Create();
var signature = dsa.SignData(data, HashAlgorithmName.SHA256);
// FIX: Use a different algorithm
using var ecdsa = ECDsa.Create();
var signature = ecdsa.SignData(data, HashAlgorithmName.SHA256);
```
**Fix:** Migrate from DSA to a more modern algorithm:
- **ECDSA** — recommended replacement for digital signatures
- **RSA** — alternative if ECDSA is not suitable
- **Ed25519** — if available in your scenario
This change only affects macOS. DSA continues to work on Windows and Linux (though it is generally considered a legacy algorithm).
### AIA certificate downloads disabled by default during client-certificate validation (Preview 3)
**Impact: Medium.** AIA (Authority Information Access) certificate downloads are now disabled by default when performing server-side client-certificate chain validation. Previously the runtime would attempt to fetch intermediate CA certificates online.
**Fix:** If using mTLS where client certificates rely on AIA URLs for intermediate CAs, either:
- Pre-install the full certificate chain on the server
- Have clients send the full chain including intermediates
- Re-enable AIA downloads via `X509ChainPolicy.DisableCertificateDownloads = false`
Source: https://github.com/dotnet/runtime/pull/125049
references/csharp-compiler-dotnet10to11.md
# C# 15 Compiler Breaking Changes (.NET 11)
These breaking changes are introduced by the Roslyn compiler shipping with the .NET 11 SDK. They affect all projects targeting `net11.0` (which uses C# 15 by default). These are maintained separately from the runtime breaking changes at: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/breaking-changes/compiler%20breaking%20changes%20-%20dotnet%2011
> **Note:** .NET 11 is in preview. Additional compiler breaking changes may be introduced in later previews.
## Source-Incompatible Changes
### Span/ReadOnlySpan collection expression safe-context changed to `declaration-block`
**Impact: Medium.** The safe-context of a collection expression of `Span<T>` or `ReadOnlySpan<T>` type is now `declaration-block`, matching the specification. Previously the compiler incorrectly used `function-member`.
This can cause new errors when assigning a span collection expression created in an inner scope to a variable in an outer scope:
```csharp
// BREAKS — new error
scoped Span<int> items1 = default;
foreach (var x in new[] { 1, 2 })
{
Span<int> items = [x];
if (x == 1)
items1 = items; // error: safe-context is declaration-block
}
// FIX option 1: Use an array type
foreach (var x in new[] { 1, 2 })
{
int[] items = [x];
if (x == 1)
items1 = items; // ok, using int[] conversion to Span<int>
}
// FIX option 2: Move collection expression to outer scope
Span<int> items = [0];
foreach (var x in new[] { 1, 2 })
{
items[0] = x;
if (x == 1)
items1 = items; // ok
}
```
See also: https://github.com/dotnet/csharplang/issues/9750
### `ref readonly` synthesized delegates require `InAttribute`
**Impact: Low.** When the compiler synthesizes a delegate type for a `ref readonly`-returning method or lambda, it now properly emits metadata requiring `System.Runtime.InteropServices.InAttribute`.
```csharp
class RefHelper
{
private static int value = 42;
public void M()
{
// May cause CS0518 if InAttribute is not available
var methodDelegate = this.MethodWithRefReadonlyReturn;
var lambdaDelegate = ref readonly int () => ref value;
}
}
```
**Fix:** Add a reference to an assembly defining `System.Runtime.InteropServices.InAttribute` (typically available via the default runtime references).
### `ref readonly` local functions require `InAttribute`
**Impact: Low.** Same as above but for `ref readonly`-returning local functions.
```csharp
void Method()
{
int x = 0;
ref readonly int local() => ref x; // CS0518 if InAttribute missing
}
```
**Fix:** Same as above — ensure `InAttribute` is available.
### Dynamic `&&`/`||` with interface left operand disallowed
**Impact: Low.** The compiler now reports a compile-time error when an interface type with `true`/`false` operators is used as the left operand of `&&` or `||` with a `dynamic` right operand. Previously this compiled but threw `RuntimeBinderException` at runtime.
```csharp
interface I1
{
static bool operator true(I1 x) => false;
static bool operator false(I1 x) => false;
}
class C1 : I1
{
public static C1 operator &(C1 x, C1 y) => x;
public static bool operator true(C1 x) => false;
public static bool operator false(C1 x) => false;
}
void M()
{
I1 x = new C1();
dynamic y = new C1();
_ = x && y; // error CS7083
}
```
**Fix:** Cast the left operand to a concrete type or to `dynamic`:
```csharp
_ = (C1)x && y; // valid
_ = (dynamic)x && y; // valid
```
See also: https://github.com/dotnet/roslyn/issues/80954
### `nameof(this.)` in attributes disallowed
**Impact: Low.** Using `this` or `base` inside `nameof` in an attribute is now properly disallowed per the language specification. This was unintentionally permitted since C# 12.
```csharp
// Before (.NET 10) — compiled but was unintentionally permitted
class C
{
string P;
[System.Obsolete(nameof(this.P))]
void M() { }
}
```
```csharp
// After (.NET 11) — remove 'this.' qualifier
class C
{
string P;
[System.Obsolete(nameof(P))]
void M() { }
}
```
See also: https://github.com/dotnet/roslyn/issues/82251
### `with()` as collection expression element (C# 15)
**Impact: Low.** When `LangVersion` is 15 or greater, `with(...)` as an element in a collection expression is treated as constructor/factory arguments (the new "collection expression arguments" feature), not as a call to a method named `with`.
```csharp
object x, y, z = ...;
object[] items;
items = [with(x, y), z]; // C# 14: call to with() method; C# 15: error
items = [@with(x, y), z]; // fix: escape to call method named 'with'
```
### Parsing of `when` in switch-expression-arm
**Impact: Low.** In a switch expression, `(X.Y) when` is now parsed as a constant pattern `(X.Y)` followed by a `when` clause. Previously it was parsed as a cast expression casting `when` to `(X.Y)`.
See also: https://github.com/dotnet/roslyn/issues/81837
## New Language Features (non-breaking but relevant)
### Collection expression arguments
C# 15 adds `with(...)` syntax as the first element of a collection expression, allowing constructor/factory arguments:
```csharp
List<string> names = [with(capacity: values.Count * 2), .. values];
HashSet<string> set = [with(StringComparer.OrdinalIgnoreCase), "Hello", "HELLO"];
```
This is the feature that causes the `with()` method call breaking change above.
references/efcore-dotnet10to11.md
# Entity Framework Core Breaking Changes (.NET 11)
These breaking changes affect projects using Entity Framework Core 11. Source: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-11.0/breaking-changes
> **Note:** .NET 11 is in preview. The changes below were introduced in **Preview 1 through Preview 3**. Additional EF Core breaking changes are expected in later previews.
## Medium-Impact Changes
### Sync I/O via the Azure Cosmos DB provider has been fully removed (Preview 1)
**Impact: Medium.** Synchronous I/O via the Azure Cosmos DB provider has been completely removed. In EF Core 10, sync I/O was unsupported by default but could be re-enabled with a special opt-in. In EF Core 11, calling any synchronous I/O API always throws — there is no opt-in to restore the old behavior.
**Affected APIs:**
- `ToList()`, `First()`, `Single()`, `Count()`, and other synchronous LINQ operators
- `SaveChanges()`
- Any synchronous query execution against the Cosmos DB provider
```csharp
// BREAKS in EF Core 11 — always throws
var items = context.Items.ToList();
context.SaveChanges();
// FIX: Use async equivalents
var items = await context.Items.ToListAsync();
await context.SaveChangesAsync();
```
**Why:** Synchronous blocking on asynchronous methods ("sync-over-async") can lead to deadlocks and performance problems. Since the Azure Cosmos DB SDK only supports async methods, the EF Cosmos provider now requires async throughout.
**Fix:** Convert all synchronous I/O calls to their async equivalents:
- `ToList()` → `await ToListAsync()`
- `First()` → `await FirstAsync()`
- `Single()` → `await SingleAsync()`
- `Count()` → `await CountAsync()`
- `SaveChanges()` → `await SaveChangesAsync()`
- `Any()` → `await AnyAsync()`
Tracking issue: https://github.com/dotnet/efcore/issues/37059
### Cosmos: empty owned collections return empty collection instead of null (Preview 1)
**Impact: Low.** When a Cosmos-backed entity has an owned collection with no items, the property now returns an empty collection rather than `null`.
**Fix:** Update null checks to empty-collection checks: `if (entity.Items is null)` → `if (entity.Items.Count == 0)`.
Tracking issue: https://github.com/dotnet/efcore/issues/36577
## Preview 3 Changes
### RelationalEventId.MigrationsNotFound now throws by default (Preview 3)
**Impact: Low.** Calling `Migrate()` or `MigrateAsync()` when no migrations exist in the assembly now throws an exception rather than silently logging.
**Fix:** If intentional, suppress with: `options.ConfigureWarnings(w => w.Ignore(RelationalEventId.MigrationsNotFound))`.
Source: https://github.com/dotnet/efcore/pull/37839
### EF Core Tools and Tasks no longer transitively depend on Design (Preview 3)
**Impact: Low.** The `Microsoft.EntityFrameworkCore.Tools` and `Microsoft.EntityFrameworkCore.Tasks` NuGet packages no longer have a transitive dependency on `Microsoft.EntityFrameworkCore.Design`.
**Fix:** If your project relied on this transitive reference, add it explicitly:
```xml
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="11.0.0" PrivateAssets="all" />
```
Source: https://github.com/dotnet/efcore/pull/37837
### EFOptimizeContext MSBuild property removed (Preview 3)
**Impact: Low.** The `<EFOptimizeContext>true</EFOptimizeContext>` MSBuild property no longer exists. Code generation is now controlled by `<EFScaffoldModelStage>` and `<EFPrecompileQueriesStage>`.
**Fix:** Replace `<EFOptimizeContext>` with the two new properties. With `PublishAOT=true`, generation is automatic during publish.
Source: https://github.com/dotnet/efcore/pull/37838
### SqlVector<T> properties excluded from SELECT by default (Preview 3)
**Impact: Low.** `SqlVector<T>` properties are now excluded from `SELECT` statements when materializing entities (they return `null`). They can still be used in `WHERE`/`ORDER BY` for vector search.
**Fix:** Use explicit projections to include vector values: `.Select(b => new { b.Id, b.Embedding })`.
Source: https://github.com/dotnet/efcore/pull/37829
### Microsoft.Data.SqlClient updated to 7.0 (Preview 3)
**Impact: Medium.** EF Core's SQL Server provider now depends on `Microsoft.Data.SqlClient` 7.0. In v7, Azure/Entra ID authentication dependencies (`Azure.Core`, `Azure.Identity`, `Microsoft.Identity.Client`) have been removed from the core package.
**Fix:** If using Entra ID authentication (e.g., `ActiveDirectoryDefault`, `ActiveDirectoryManagedIdentity`), add:
```xml
<PackageReference Include="Microsoft.Data.SqlClient.Extensions.Azure" Version="7.0.0" />
```
Source: https://github.com/dotnet/efcore/pull/37949
### Encryption-enabled SQLite packages removed (Preview 3)
**Impact: Medium.** `SQLitePCLRaw 3.0` (used by `Microsoft.Data.Sqlite` 11) removed `bundle_e_sqlcipher` and several other bundle packages.
**Fix:** Switch to SQLite Encryption Extension (SEE), SQLCipher from Zetetic, or `SQLite3MultipleCiphers-NuGet`.
Source: https://github.com/dotnet/efcore/issues/37059
references/runtime-jit-dotnet10to11.md
# Runtime and JIT Compiler Breaking Changes (.NET 11)
These breaking changes affect the .NET runtime and JIT compiler. Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/11
> **Note:** .NET 11 is in preview. Additional runtime breaking changes are expected in later previews.
## Behavioral Changes
### Minimum hardware requirements updated
**Impact: High for deployments on older hardware.** .NET 11 updates the minimum hardware requirements for both x86/x64 and Arm64 architectures.
#### x86/x64 changes
The baseline is updated from `x86-64-v1` to `x86-64-v2` on all operating systems. This means the minimum CPU must support:
- `CMOV`, `CX8`, `SSE`, `SSE2` (previously required)
- `CX16`, `POPCNT`, `SSE3`, `SSSE3`, `SSE4.1`, `SSE4.2` (newly required)
This aligns with Windows 11 requirements and covers all Intel/AMD CPUs still in official support (older chips went out of support around 2013).
The ReadyToRun (R2R) target is updated to `x86-64-v3` for Windows and Linux, adding `AVX`, `AVX2`, `BMI1`, `BMI2`, `F16C`, `FMA`, `LZCNT`, and `MOVBE`. Hardware that meets `x86-64-v2` but not `x86-64-v3` will experience additional JIT overhead at startup.
| OS | Previous JIT/AOT min | New JIT/AOT min | Previous R2R target | New R2R target |
|----|---------------------|-----------------|--------------------|--------------------|
| Apple | x86-64-v1 | x86-64-v2 | x86-64-v2 | (No change) |
| Linux | x86-64-v1 | x86-64-v2 | x86-64-v2 | x86-64-v3 |
| Windows | x86-64-v1 | x86-64-v2 | x86-64-v2 | x86-64-v3 |
#### Arm64 changes
- **Apple**: No change to minimum hardware or R2R target.
- **Linux**: No change to minimum hardware (still supports Raspberry Pi). R2R target updated to include `LSE`.
- **Windows**: Baseline updated to require `LSE` (Load-Store Exclusive), required by Windows 11 and all Arm64 CPUs officially supported by Windows 10. R2R target updated to `armv8.2-a + RCPC`.
| OS | Previous JIT/AOT min | New JIT/AOT min | Previous R2R target | New R2R target |
|----|---------------------|-----------------|--------------------|--------------------|
| Apple | Apple M1 | (No change) | Apple M1 | (No change) |
| Linux | armv8.0-a | (No change) | armv8.0-a | armv8.0-a + LSE |
| Windows | armv8.0-a | armv8.0-a + LSE | armv8.0-a | armv8.2-a + RCPC |
#### Impact
Starting with .NET 11, .NET fails to run on older hardware and prints:
> The current CPU is missing one or more of the baseline instruction sets.
For ReadyToRun-capable assemblies, there may be additional startup overhead on supported hardware that doesn't meet the R2R target.
**Fix:** Verify all deployment targets meet the new minimum requirements. For x86/x64, any CPU from ~2013 or later should be fine. For Windows Arm64, ensure `LSE` support (all Windows 11 compatible Arm64 devices).
Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/jit/11/minimum-hardware-requirements
### NativeAOT native-library outputs use `lib` prefix on Unix (Preview 3)
**Impact: Low.** NativeAOT shared/native library outputs on Linux and macOS now follow Unix conventions and include the `lib` prefix (e.g., `libMyLib.so` instead of `MyLib.so`).
**Fix:** Update build scripts, deployment pipelines, or P/Invoke declarations that reference output filenames by the old name without the `lib` prefix.
Source: https://github.com/dotnet/runtime/pull/124611
references/sdk-msbuild-dotnet10to11.md
# SDK and MSBuild Breaking Changes (.NET 11)
These changes affect the .NET SDK, CLI tooling, NuGet, and MSBuild behavior. Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/11
> **Note:** .NET 11 is in preview. Additional SDK/MSBuild breaking changes are expected in later previews.
## Behavioral Changes
### Mono launch target not set for .NET Framework apps
**Impact: Low.** The mono launch target is no longer set automatically for .NET Framework apps. If you require Mono for execution on Linux, you need to specify it explicitly in the configuration.
Source: https://learn.microsoft.com/en-us/dotnet/core/compatibility/sdk/11/mono-launch-target-removed
### NETSDK1235 warning for PackAsTool with custom .nuspec (Preview 2)
**Impact: Low.** A new build warning `NETSDK1235` is emitted when a project has both `PackAsTool=true` and a custom `NuspecFile` property, which violates .NET Tool packaging requirements. Projects with `TreatWarningsAsErrors=true` will fail.
**Fix:** Remove the custom `NuspecFile` property when packaging as a .NET Tool, or suppress the warning if the .nuspec is compatible.
Source: https://github.com/dotnet/sdk/pull/52810
### `dotnet publish --self-contained` now parses the passed value (Preview 3)
**Impact: Low.** `dotnet publish --self-contained` previously always interpreted the flag as `true` regardless of the passed value. It now correctly parses the value (e.g., `--self-contained false` actually produces a framework-dependent publish).
**Fix:** Review build scripts that pass `--self-contained` to ensure the intended value is correct.
Source: https://github.com/dotnet/sdk/pull/52333
SKILL.md
---
name: migrate-dotnet10-to-dotnet11
description: >
Migrate a .NET 10 project or solution to .NET 11 and resolve all breaking changes.
This is a MIGRATION skill — use it when upgrading from .NET 10 to .NET 11,
NOT for writing new programs.
USE FOR: upgrading TargetFramework from net10.0 to net11.0, fixing build errors
after updating the .NET 11 SDK, resolving source-breaking and behavioral changes
in .NET 11 runtime, C# 15 compiler, and EF Core 11, adapting to updated minimum
hardware requirements (x86-64-v2, Arm64 LSE), and updating CI/CD pipelines and
Dockerfiles for .NET 11.
DO NOT USE FOR: .NET Framework migrations, upgrading from .NET 9 or earlier,
greenfield .NET 11 projects, or cosmetic modernization unrelated to the upgrade.
NOTE: .NET 11 is in preview. Covers breaking changes through Preview 3.
license: MIT
---
# .NET 10 → .NET 11 Migration
Migrate a .NET 10 project or solution to .NET 11, systematically resolving all breaking changes. The outcome is a project targeting `net11.0` that builds cleanly, passes tests, and accounts for every behavioral, source-incompatible, and binary-incompatible change introduced in .NET 11.
> **Note:** .NET 11 is currently in preview. This skill covers breaking changes documented through Preview 3.
## When to Use
- Upgrading `TargetFramework` from `net10.0` to `net11.0`
- Resolving build errors or new warnings after updating the .NET 11 SDK
- Adapting to behavioral changes in .NET 11 runtime, ASP.NET Core 11, or EF Core 11
- Updating CI/CD pipelines, Dockerfiles, or deployment scripts for .NET 11
- Fixing C# 15 compiler breaking changes after SDK upgrade
## When Not to Use
- The project already targets `net11.0` and builds cleanly — migration is done
- Upgrading from .NET 9 or earlier — address the .NET 9→10 breaking changes first
- Migrating from .NET Framework — that is a separate, larger effort
- Greenfield projects that start on .NET 11 (no migration needed)
## Inputs
| Input | Required | Description |
|-------|----------|-------------|
| Project or solution path | Yes | The `.csproj`, `.sln`, or `.slnx` entry point to migrate |
| Build command | No | How to build (e.g., `dotnet build`, a repo build script). Auto-detect if not provided |
| Test command | No | How to run tests (e.g., `dotnet test`). Auto-detect if not provided |
| Project type hints | No | Whether the project uses ASP.NET Core, EF Core, Cosmos DB, etc. Auto-detect from PackageReferences and SDK attributes if not provided |
## Workflow
> **Answer directly from the loaded reference documents for information about .NET 11 breaking changes.** You may inspect the local repository (project/solution files, source code, configuration, build/test scripts) as needed to determine which changes apply. Do not fetch web pages or other external sources for breaking change information — the loaded references are the authoritative source. Focus on identifying which breaking changes apply and providing concrete fixes.
>
> **Commit strategy:** Commit at each logical boundary — after updating the TFM (Step 2), after resolving build errors (Step 3), after addressing behavioral changes (Step 4), and after updating infrastructure (Step 5). This keeps each commit focused and reviewable.
### Step 1: Assess the project
1. Identify how the project is built and tested. Look for build scripts, `.sln`/`.slnx` files, or individual `.csproj` files.
2. Run `dotnet --version` to confirm the .NET 11 SDK is installed. If it is not, stop and inform the user.
3. Determine which technology areas the project uses by examining:
- **SDK attribute**: `Microsoft.NET.Sdk.Web` → ASP.NET Core; `Microsoft.NET.Sdk.WindowsDesktop` with `<UseWPF>` or `<UseWindowsForms>` → WPF/WinForms
- **PackageReferences**: `Microsoft.EntityFrameworkCore.*` → EF Core; `Microsoft.EntityFrameworkCore.Cosmos` → Cosmos DB provider
- **Dockerfile presence** → Container changes relevant
- **Cryptography API usage** → DSA on macOS affected; AIA cert download changes relevant
- **Compression API usage** → DeflateStream/GZipStream/ZipArchive changes relevant
- **TAR API usage** → Header checksum validation and HardLink entry changes relevant
- **`NamedPipeClientStream` usage with `SafePipeHandle`** → SYSLIB0063 constructor obsoletion relevant
- **`BackgroundService` usage** → Unhandled exceptions now stop the host
- **`Microsoft.OpenApi` direct usage** → v3 API breaking changes in ASP.NET Core OpenAPI
- **EF Core SQL Server with Entra ID auth** → SqlClient 7.0 auth dependency changes
- **NativeAOT native libraries on Unix** → Output filename prefix changed
4. Record which reference documents are relevant (see the reference loading table in Step 3).
5. Do a **clean build** (`dotnet build --no-incremental` or delete `bin`/`obj`) on the current `net10.0` target to establish a clean baseline. Record any pre-existing warnings.
### Step 2: Update the Target Framework
1. In each `.csproj` (or `Directory.Build.props` if centralized), change:
```xml
<TargetFramework>net10.0</TargetFramework>
```
to:
```xml
<TargetFramework>net11.0</TargetFramework>
```
For multi-targeted projects, add `net11.0` to `<TargetFrameworks>` or replace `net10.0`.
2. Update all `Microsoft.Extensions.*`, `Microsoft.AspNetCore.*`, `Microsoft.EntityFrameworkCore.*`, and other Microsoft package references to their 11.0.x versions. If using Central Package Management (`Directory.Packages.props`), update versions there.
3. Run `dotnet restore`. Fix any restore errors before continuing.
4. Run `dotnet build`. Capture all errors and warnings — these will be addressed in Step 3.
### Step 3: Fix source-breaking and compilation changes
Load reference documents based on the project's technology areas:
| Reference file | When to load |
|----------------|-------------|
| `references/csharp-compiler-dotnet10to11.md` | Always (C# 15 compiler breaking changes) |
| `references/core-libraries-dotnet10to11.md` | Always (applies to all .NET 11 projects) |
| `references/sdk-msbuild-dotnet10to11.md` | Always (SDK and build tooling changes) |
| `references/aspnetcore-dotnet10to11.md` | Project uses ASP.NET Core (OpenAPI, Blazor) |
| `references/efcore-dotnet10to11.md` | Project uses Entity Framework Core |
| `references/cryptography-dotnet10to11.md` | Project uses cryptography APIs, mTLS, or targets macOS |
| `references/runtime-jit-dotnet10to11.md` | Deploying to older hardware, embedded devices, or using NativeAOT |
Work through each build error systematically. Common patterns:
1. **C# 15 Span collection expression safe-context** — Collection expressions of `Span<T>`/`ReadOnlySpan<T>` type now have `declaration-block` safe-context. Code assigning span collection expressions to variables in outer scopes will error. Use array type or move the expression to the correct scope.
2. **`ref readonly` delegates/local functions need `InAttribute`** — If synthesizing delegates from `ref readonly`-returning methods or using `ref readonly` local functions, ensure `System.Runtime.InteropServices.InAttribute` is available.
3. **`nameof(this.)` in attributes** — Remove `this.` qualifier; use `nameof(P)` instead of `nameof(this.P)`.
4. **`with()` in collection expressions (C# 15)** — `with(...)` is now treated as constructor arguments, not a method call. Use `@with(...)` to call a method named `with`.
5. **Dynamic `&&`/`||` with interface operand** — Interface types as left operand of `&&`/`||` with `dynamic` right operand now errors at compile time. Cast to concrete type or `dynamic`.
6. **EF Core Cosmos sync I/O removal** — `ToList()`, `SaveChanges()`, etc. on Cosmos provider always throw. Convert to async equivalents.
7. **SYSLIB0063: `NamedPipeClientStream` `isConnected` parameter obsoleted** — The constructor overload taking `bool isConnected` is obsoleted. Remove the `isConnected` argument and use the new 3-parameter constructor. Projects with `TreatWarningsAsErrors` will fail to build.
8. **`when` switch-expression-arm parsing** — `(X.Y) when` is now parsed as a constant pattern with a `when` clause instead of a cast expression, which can cause existing code to fail to compile or change meaning. Review switch expressions using `when` and adjust syntax as needed.
9. **Microsoft.OpenApi v3 breaking changes** — `Microsoft.AspNetCore.OpenApi` now depends on `Microsoft.OpenApi` 3.x. Code using `Microsoft.OpenApi` types directly (`OpenApiDocument`, `OpenApiSchema`, etc.) will have compile errors. Follow the v3 upgrade guide.
10. **EF Core Design package no longer transitive** — `Microsoft.EntityFrameworkCore.Tools` and `.Tasks` no longer depend on `.Design`. Add an explicit `PackageReference` if needed.
11. **EFOptimizeContext MSBuild property removed** — Replace with `<EFScaffoldModelStage>` and `<EFPrecompileQueriesStage>`.
### Step 4: Address behavioral changes
These changes compile successfully but alter runtime behavior. Review each one and determine impact:
1. **DeflateStream/GZipStream empty payload** — Now writes headers and footers even for empty payloads. If your code checks for zero-length output, update the check.
2. **MemoryStream maximum capacity** — Maximum capacity updated and exception behavior changed. Review code that creates large MemoryStreams or relies on specific exception types.
3. **TAR header checksum validation** — TAR-reading APIs now verify checksums. Corrupted or hand-crafted TAR files may now fail to read.
4. **ZipArchive.CreateAsync eager loading** — `ZipArchive.CreateAsync` eagerly loads entries. May affect memory usage for large archives.
5. **Environment.TickCount consistency** — Made consistent with Windows timeout behavior. Code relying on specific tick count behavior may need adjustment.
6. **DSA removed from macOS** — DSA cryptographic operations throw on macOS. Use a different algorithm (RSA, ECDSA).
7. **Japanese Calendar minimum date** — Minimum supported date corrected. Code using very early Japanese Calendar dates may be affected.
8. **Minimum hardware requirements** — x86/x64 baseline moved to `x86-64-v2`; Windows Arm64 requires `LSE`. Verify deployment targets meet requirements.
9. **Mono launch target for .NET Framework** — No longer set automatically. If using Mono for .NET Framework apps on Linux, specify explicitly.
10. **Unhandled BackgroundService exceptions stop the host** — Exceptions from `ExecuteAsync()` now propagate and crash the host. Add try/catch in background services that should not bring down the application.
11. **ZipArchive CRC32 validation** — ZIP reads now validate CRC32 checksums. Corrupt or truncated archives that previously succeeded will now throw `InvalidDataException`.
12. **TarWriter emits HardLink entries** — Hard-linked files are now written as `HardLink` entries instead of duplicated data. Consumers of .NET-produced tar archives must handle `HardLink` entries.
13. **AIA certificate downloads disabled** — Server-side client-certificate validation no longer downloads intermediate CAs via AIA by default. Pre-install the full chain or have clients send intermediates.
14. **Blazor Virtualize OverscanCount default changed** — Default `OverscanCount` changed from 3 to 15. Set explicitly if performance-sensitive.
15. **Microsoft.Data.SqlClient 7.0 — Entra ID auth separated** — Azure/Entra ID authentication dependencies removed from the core SqlClient package. Add `Microsoft.Data.SqlClient.Extensions.Azure` if using Entra ID auth.
16. **SqlVector<T> excluded from SELECT** — Vector properties are no longer auto-loaded. Use explicit projections to include vector values.
17. **SQLitePCLRaw encryption bundles removed** — `bundle_e_sqlcipher` and other encryption bundle packages removed in SQLitePCLRaw 3.0.
18. **NativeAOT Unix native library `lib` prefix** — Output filenames now include `lib` prefix on Linux/macOS (e.g., `libMyLib.so`).
### Step 5: Update infrastructure
1. **Dockerfiles**: Update base images from 10.0 to 11.0:
```dockerfile
# Before
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
FROM mcr.microsoft.com/dotnet/aspnet:10.0
# After
FROM mcr.microsoft.com/dotnet/sdk:11.0 AS build
FROM mcr.microsoft.com/dotnet/aspnet:11.0
```
2. **CI/CD pipelines**: Update SDK version references. If using `global.json`, update the `sdk.version` in your existing file while preserving other keys (such as `rollForward` and test configuration):
```diff
{
"sdk": {
- "version": "10.0.100",
- "rollForward": "latestFeature"
+ "version": "11.0.100-preview.3",
+ "rollForward": "latestFeature"
},
"otherSettings": {
"...": "..."
}
}
```
3. **Hardware deployment targets**: Verify all deployment targets meet the updated minimum hardware requirements (x86-64-v2 for x86/x64, LSE for Windows Arm64).
### Step 6: Verify
1. Run a full clean build: `dotnet build --no-incremental`
2. Run all tests: `dotnet test`
3. If the application is containerized, build and test the container image
4. Smoke-test the application, paying special attention to:
- Compression behavior with empty streams
- TAR file reading (checksum validation and HardLink entries)
- EF Core Cosmos DB operations (must be async)
- DSA usage on macOS
- Memory-intensive MemoryStream usage
- Span collection expression assignments
- BackgroundService exception handling
- mTLS / client certificate chain validation
- EF Core SQL Server with Entra ID authentication
- NativeAOT output filenames on Unix
5. Review the diff and ensure no unintended behavioral changes were introduced
## Reference Documents
The `references/` folder contains detailed breaking change information organized by technology area. Load only the references relevant to the project being migrated:
| Reference file | When to load |
|----------------|-------------|
| `references/csharp-compiler-dotnet10to11.md` | Always (C# 15 compiler breaking changes) |
| `references/core-libraries-dotnet10to11.md` | Always (applies to all .NET 11 projects) |
| `references/sdk-msbuild-dotnet10to11.md` | Always (SDK and build tooling changes) |
| `references/aspnetcore-dotnet10to11.md` | Project uses ASP.NET Core (OpenAPI, Blazor) |
| `references/efcore-dotnet10to11.md` | Project uses Entity Framework Core |
| `references/cryptography-dotnet10to11.md` | Project uses cryptography APIs, mTLS, or targets macOS |
| `references/runtime-jit-dotnet10to11.md` | Deploying to older hardware, embedded devices, or using NativeAOT |