dotnet/wpf · error · ArgumentOutOfRangeException

ArgumentOutOfRangeException (Parameter 'origin')

Error message

ArgumentOutOfRangeException (Parameter 'origin')

What it means

ArgumentOutOfRangeException named 'origin' thrown by SparseMemoryStream.Seek when the seek origin is not Begin, Current, or End. Any value outside the SeekOrigin enum (e.g. a cast of an invalid int) falls into the else branch and is rejected before any position arithmetic happens.

Solutions

  1. Pass only SeekOrigin.Begin, SeekOrigin.Current, or SeekOrigin.End.
  2. Validate the origin value before casting int -> SeekOrigin.
  3. Fix the caller that computes the origin dynamically to use Enum.IsOrigin checks.

Example fix

// before
stream.Seek(offset, (SeekOrigin)someInt); // someInt may be invalid
// after
if (Enum.IsDefined(typeof(SeekOrigin), someInt))
    stream.Seek(offset, (SeekOrigin)someInt);
Defensive patterns

Strategy: validation

Validate before calling

if (!Enum.IsDefined(typeof(SeekOrigin), origin)) throw new ArgumentOutOfRangeException(nameof(origin));

Type guard

bool IsValidSeekOrigin(SeekOrigin o) => o is SeekOrigin.Begin or SeekOrigin.Current or SeekOrigin.End;

Try / catch

try { stream.Seek(offset, origin); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "origin") { /* fix origin value */ }

Prevention

When it happens

Trigger: Calling SparseMemoryStream.Seek(offset, (SeekOrigin)99) or passing an uninitialized/invalid SeekOrigin obtained via unsafe casting or default(int) conversion.

Common situations: Generic stream-wrapper code that forwards an origin parameter cast from an int without validating it; interop code marshaling seek origins from native enums.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/1ec064268edd90f2. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/SparseMemoryStream.cs:154

        {
            CheckDisposed();
            long newStreamPosition = _currentStreamPosition;

            if (origin ==SeekOrigin.Begin)
            {
                newStreamPosition = offset;
            }
            else if  (origin == SeekOrigin.Current)
            {
                checked { newStreamPosition += offset; }
            }
            else if  (origin == SeekOrigin.End)
            {
                checked { newStreamPosition = _currentStreamLength + offset; }
            }
            else
            {
                throw new ArgumentOutOfRangeException(nameof(origin));
            }

            if (newStreamPosition  < 0)
            {
                 throw new ArgumentException(SR.SeekNegative);
            }
            _currentStreamPosition = newStreamPosition;

            return _currentStreamPosition;
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            Debug.Assert(_currentStreamPosition >= 0);

View on GitHub (pinned to 81131a70a4)