Breaking changes in .NET 9

If you're migrating an app to .NET 9, the breaking changes listed here might affect you. Changes are grouped by technology area, such as ASP.NET Core or Windows Forms.

This article categorizes each breaking change as binary incompatible or source incompatible, or as a behavioral change:

  • Binary incompatible - When run against the new runtime or component, existing binaries may encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.

  • Source incompatible - When recompiled using the new SDK or component or to target the new runtime, existing source code may require source changes to compile successfully.

  • Behavioral change - Existing code and binaries may behave differently at run time. If the new behavior is undesirable, existing code would need to be updated and recompiled.

Note

This article is a work in progress. It's not a complete list of breaking changes in .NET 9. To query breaking changes that are still pending publication, see Issues of .NET.

ASP.NET Core

Title Type of change Introduced version
DefaultKeyResolution.ShouldGenerateNewKey has altered meaning Behavioral change Preview 3
Dev cert export no longer creates folder Behavioral change RC 1
HostBuilder enables ValidateOnBuild/ValidateScopes in development environment Behavioral change Preview 7
Middleware types with multiple constructors Behavioral change RC 1

Containers

Title Type of change Introduced version
.NET 9 container images no longer install zlib Behavioral change Preview 7

Core .NET libraries

Title Type of change Introduced version
Adding a ZipArchiveEntry with CompressionLevel sets ZIP central directory header general-purpose bit flags Behavioral change Preview 5
Altered UnsafeAccessor support for non-open generics Behavioral change Preview 6
API obsoletions with custom diagnostic IDs Source incompatible (Multiple)
BigInteger maximum length Behavioral change Preview 6
BinaryReader.GetString() returns "\uFFFD" on malformed sequences Behavioral change Preview 7
Creating type of array of System.Void not allowed Behavioral change Preview 1
Default Equals() and GetHashCode() throw for types marked with InlineArrayAttribute Behavioral change Preview 6
EnumConverter validates registered types to be enum Behavioral change Preview 7
FromKeyedServicesAttribute no longer injects non-keyed parameter Behavioral change RC 1
IncrementingPollingCounter initial callback is asynchronous Behavioral change RC 1
Inline array struct size limit is enforced Behavioral change Preview 1
InMemoryDirectoryInfo prepends rootDir to files Behavioral change Preview 1
New TimeSpan.From*() overloads that take integers Source incompatible Preview 3
RuntimeHelpers.GetSubArray returns different type Behavioral change Preview 1
String.Trim(params ReadOnlySpan<char>) overload removed Source/binary incompatible GA
Support for empty environment variables Behavioral change Preview 6
ZipArchiveEntry names and comments respect UTF8 flag Behavioral change RC 1

Cryptography

Title Type of change Introduced version
SafeEvpPKeyHandle.DuplicateHandle up-refs the handle Behavioral change Preview 7
Some X509Certificate2 and X509Certificate constructors are obsolete Source incompatible Preview 7
Windows private key lifetime simplified Behavioral change Preview 7

Deployment

Title Type of change Introduced version
Deprecated desktop Windows/macOS/Linux MonoVM runtime packages Source incompatible Preview 7

Interop

Title Type of change Introduced version
CET supported by default Binary incompatible Preview 6

JIT compiler

Title Type of change Introduced version
Floating point to integer conversions are saturating Behavioral change Preview 4
Some SVE APIs removed Source incompatible RC 2

Networking

Title Type of change Introduced version
API obsoletions Source incompatible Preview 6
HttpClient metrics report server.port unconditionally Behavioral change Preview 7
HttpClientFactory logging redacts header values by default Behavioral change RC 1
HttpClientFactory uses SocketsHttpHandler as primary handler Behavioral change Preview 6
HttpListenerRequest.UserAgent is nullable Source incompatible Preview 1
URI query redaction in HttpClient EventSource events Behavioral change Preview 7
URI query redaction in IHttpClientFactory logs Behavioral change Preview 7

SDK and MSBuild

Title Type of change Introduced version
dotnet restore audits transitive packages Behavioral change Preview 6
dotnet watch incompatible with Hot Reload for old frameworks Behavioral change RC 1
dotnet workload commands output change Behavioral change Preview 1
installer repo version no longer documented Behavioral change Preview 5
Terminal logger is default Behavioral change Preview 1
Version requirements for .NET 9 SDK Source incompatible GA
Warning emitted for .NET Standard 1.x target Source incompatible Preview 6
Warning emitted for .NET 7 target Source incompatible GA

Serialization

Title Type of change Introduced version
BinaryFormatter always throws Behavioral change Preview 6

Windows Forms

Title Type of change Introduced version
BindingSource.SortDescriptions doesn't return null Behavioral change Preview 1
Changes to nullability annotations Source incompatible Preview 1
ComponentDesigner.Initialize throws ArgumentNullException Behavioral change Preview 1
DataGridViewRowAccessibleObject.Name starting row index Behavioral change Preview 1
IMsoComponent support is opt-in Behavioral change Preview 2
New security analyzers Source incompatible RC 1
No exception if DataGridView is null Behavioral change Preview 1
PictureBox raises HttpClient exceptions Behavioral change Preview 6

WPF

Title Type of change Introduced version
GetXmlNamespaceMaps type change Behavioral change/Source incompatible Preview 3

See also