diff --git a/docs/core/compatibility/11.md b/docs/core/compatibility/11.md index 62c9c8cce0734..38e7062d947b6 100644 --- a/docs/core/compatibility/11.md +++ b/docs/core/compatibility/11.md @@ -19,6 +19,7 @@ If you're migrating an app to .NET 11, the breaking changes listed here might af | Title | Type of change | |-------------------------------------------------------------------|-------------------| | [Environment.TickCount made consistent with Windows timeout behavior](core-libraries/11/environment-tickcount-windows-behavior.md) | Behavioral change | +| [MemoryStream maximum capacity updated and exception behavior changed](core-libraries/11/memorystream-max-capacity.md) | Behavioral change | ## Globalization diff --git a/docs/core/compatibility/core-libraries/11/memorystream-max-capacity.md b/docs/core/compatibility/core-libraries/11/memorystream-max-capacity.md new file mode 100644 index 0000000000000..7754b170ffd4e --- /dev/null +++ b/docs/core/compatibility/core-libraries/11/memorystream-max-capacity.md @@ -0,0 +1,90 @@ +--- +title: "Breaking change: MemoryStream maximum capacity updated and exception behavior changed" +description: "Learn about the breaking change in .NET 11 where MemoryStream enforces a maximum capacity and throws ArgumentOutOfRangeException for invalid capacity values." +ms.date: 01/08/2026 +ai-usage: ai-assisted +--- + +# MemoryStream maximum capacity updated and exception behavior changed + +The class now enforces a maximum capacity of `0x7FFFFFC7` bytes, which is the actual maximum length of a byte array supported by the CLR. Additionally, the exception behavior has changed when attempting to set a `MemoryStream`'s capacity or length beyond this maximum. Instead of throwing an , the `MemoryStream` now throws an for invalid capacity or length values. + +## Version introduced + +.NET 11 Preview 1 + +## Previous behavior + +Previously, `MemoryStream` allowed capacities up to `int.MaxValue` (`0x7FFFFFFF`), which could result in an when attempting to allocate memory beyond the CLR's supported limit of `0x7FFFFFC7`. + +When setting the capacity or length of a `MemoryStream` to a value greater than the supported limit, an `OutOfMemoryException` was thrown. + +```csharp +var stream = new MemoryStream(); +stream.SetLength(int.MaxValue); // Threw OutOfMemoryException. +``` + +## New behavior + +Starting in .NET 11, `MemoryStream` enforces a maximum capacity of `0x7FFFFFC7` bytes. Attempting to set the capacity or length beyond this limit throws an . + +The exception type for invalid capacity or length values has changed from `OutOfMemoryException` to `ArgumentOutOfRangeException`. + +```csharp +var stream = new MemoryStream(); +stream.SetLength(int.MaxValue); // Throws ArgumentOutOfRangeException. +``` + +## Type of breaking change + +This change is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +This change was introduced to align `MemoryStream`'s behavior with the actual memory allocation limits of the CLR. The previous behavior allowed developers to specify capacities or lengths that exceeded the supported limit, leading to runtime failures with less descriptive exceptions (`OutOfMemoryException`). By capping the maximum capacity and throwing `ArgumentOutOfRangeException`, the change improves runtime reliability and provides clearer feedback to developers. + +## Recommended action + +Review any code that sets the capacity or length of a `MemoryStream` to ensure it doesn't exceed the maximum supported capacity. + +If your code was catching `OutOfMemoryException` when working with `MemoryStream` capacity or length operations, you should update it to also catch `ArgumentOutOfRangeException`, as both exceptions can still occur: + +- `ArgumentOutOfRangeException` is thrown when attempting to set an invalid capacity or length (exceeding the maximum). +- `OutOfMemoryException` can still be thrown if there's insufficient memory available on the machine. + +```csharp +var stream = new MemoryStream(); +try +{ + stream.SetLength(someLength); +} +catch (ArgumentOutOfRangeException) +{ + // Handle invalid capacity/length scenario. +} +catch (OutOfMemoryException) +{ + // Handle out of memory scenario. +} +``` + +You can also add a check before setting the capacity or length to avoid the exception: + +```csharp +bool TrySetLength(MemoryStream stream, long length) +{ + if (length > Array.MaxLength) + { + return false; + } + + stream.SetLength(length); + return true; +} +``` + +## Affected APIs + +- +- +- [MemoryStream constructor](xref:System.IO.MemoryStream.%23ctor) diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 7d17ec4e0fcd7..b0919f94fd835 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -12,6 +12,8 @@ items: items: - name: Environment.TickCount made consistent with Windows timeout behavior href: core-libraries/11/environment-tickcount-windows-behavior.md + - name: MemoryStream maximum capacity updated and exception behavior changed + href: core-libraries/11/memorystream-max-capacity.md - name: Globalization items: - name: Japanese Calendar minimum supported date corrected