dotnet/wpf · error · ArgumentOutOfRangeException

ArgumentOutOfRangeException: offset is outside the valid…

Error message

ArgumentOutOfRangeException: offset is outside the valid stream range (nameof(offset))

What it means

SharedStream.Seek computes the new position from the given offset and origin; if the result is negative or >= the stream window's _length, the offset is outside the valid stream range and ArgumentOutOfRangeException is thrown. SharedStream only exposes its fixed window, not the whole base stream.

Solutions

  1. Clamp/validate offsets against the SharedStream's own Length property (the window size), not the base stream's.
  2. Compute End-relative seeks with offsets in [-Length, 0].
  3. Check that the resource wasn't truncated — compare expected BAML size with the window length.
  4. Guard with: if (offset < 0 || offset >= stream.Length) skip/throw a domain error before calling Seek.

Example fix

// before
stream.Seek(baseStream.Length - footerSize, SeekOrigin.Begin); // may exceed shared window
// after
long pos = stream.Length - footerSize;
if (pos >= 0) stream.Seek(pos, SeekOrigin.Begin);
Defensive patterns

Strategy: validation

Validate before calling

// Validate offset against the SharedStream window before Seek
void SafeSeek(Stream s, long offset, SeekOrigin origin)
{
    long target = origin switch
    {
        SeekOrigin.Begin => offset,
        SeekOrigin.Current => s.Position + offset,
        SeekOrigin.End => s.Length + offset,
        _ => long.MinValue
    };
    if (target < 0 || target >= s.Length) throw new IOException($"offset {offset} outside stream window 0..{s.Length}");
    s.Seek(offset, origin);
}

Try / catch

try
{
    stream.Seek(offset, SeekOrigin.Begin);
}
catch (ArgumentOutOfRangeException)
{
    // clamp into the shared window instead of crashing
    stream.Seek(0, SeekOrigin.Begin);
}

Prevention

When it happens

Trigger: Calling Seek with (offset, SeekOrigin.Begin) where offset < 0 or offset >= window length, or with SeekOrigin.End where offset pushes past 0.._length bounds (e.g. Seek(-_length-1, End), or offsets computed from the full base stream's length instead of the shared window's length).

Common situations: Using the underlying stream's total Length instead of SharedStream's windowed Length to compute positions; skipping a magic header with a too-large jump; reading a truncated BAML whose recorded offsets exceed the actual shared window.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/SharedStream.cs:239

                case SeekOrigin.Begin:
                    newPosition = offset;
                    break;

                case SeekOrigin.Current:
                    newPosition = _position + offset;
                    break;

                case SeekOrigin.End:
                    newPosition = _length + offset;
                    break;

                default:
                    throw new InvalidEnumArgumentException(nameof(origin), (int)origin, typeof(SeekOrigin));
            }

            if (newPosition < 0 || newPosition >= _length)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), offset, string.Empty);
            }

            CheckDisposed();

            _position = newPosition;

            return _position;
        }

        public override void SetLength(long value)
        {
            throw new NotSupportedException();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {

View on GitHub (pinned to 81131a70a4)