dotnet/wpf · error · ArgumentOutOfRangeException

Cannot set seek pointer to a negative position.

Error message

Cannot set seek pointer to a negative position.

What it means

RightsManagementEncryptedStream.Seek validates the computed position before applying it. When the seek origin (Begin/Current/End) combined with the offset yields a negative position, the stream throws ArgumentOutOfRangeException rather than allowing an invalid stream cursor. This mirrors the contract of System.IO.Stream.Seek, where positions must be >= 0.

Solutions

  1. Check that offset + current position (for SeekOrigin.Current) or offset alone (for SeekOrigin.Begin) is >= 0 before calling Seek.
  2. For SeekOrigin.End, clamp the offset so |offset| <= stream length: long safeOffset = Math.Max(offset, -stream.Length);
  3. Compute the absolute target position with Math.Max(0, target) when negative positions are semantically meaningless for your reader.
  4. If the negative value comes from parsed package metadata, re-verify/correct the data source; the stream itself is healthy.
  5. Wrap Seek in try-catch (ArgumentOutOfRangeException) if inputs are untrusted, and recover by seeking to 0.

Example fix

// before
encryptedStream.Seek(-100, SeekOrigin.Begin);
// after
long target = Math.Max(0, -100);
encryptedStream.Seek(target, SeekOrigin.Begin);
Defensive patterns

Strategy: validation

Validate before calling

long target = origin switch
{
    SeekOrigin.Begin => offset,
    SeekOrigin.Current => stream.Position + offset,
    SeekOrigin.End => stream.Length + offset,
    _ => throw new ArgumentOutOfRangeException(nameof(origin))
};
if (target < 0) target = 0; // or reject

Type guard

bool IsValidSeek(long length, long offset, SeekOrigin origin)
{
    long target = origin switch
    {
        SeekOrigin.Begin => offset,
        SeekOrigin.Current => stream.Position + offset,
        SeekOrigin.End => length + offset,
        _ => long.MinValue
    };
    return target >= 0;
}

Try / catch

try { stream.Seek(offset, origin); }
catch (ArgumentOutOfRangeException ex) { /* clamp or report: ex.ParamName == "offset" */ stream.Seek(0, SeekOrigin.Begin); }

Prevention

When it happens

Trigger: Calling Seek(offset, SeekOrigin.Begin) with a negative offset; Seek(offset, SeekOrigin.Current) when the current _streamPosition plus offset is negative; Seek(offset, SeekOrigin.End) with an offset whose absolute value exceeds the cached stream length.

Common situations: Computing a seek offset from parsed lengths or user data without clamping; seeking backwards past the start while reading an encrypted rights-managed package; a corrupted length header causing End-relative math to go negative.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptedStream.cs:149

                        {
                            temp = _streamPosition + offset;
                            break;
                        }
                    case SeekOrigin.End:
                        {
                            temp = Length + offset;
                            break;
                        }
                    default:
                        {
                            throw new ArgumentOutOfRangeException(nameof(origin), SR.SeekOriginInvalid);
                        }
                }
            }
            
            if (temp < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset), SR.SeekNegative);
            }

            _streamPosition = temp;
            return _streamPosition;
        }        

        /// <summary>
        /// See .NET Framework SDK under System.IO.Stream
        /// </summary>
        public override void SetLength(long newLength)
        {
            CheckDisposed(); 
            
            if (newLength < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(newLength), SR.CannotMakeStreamLengthNegative);
            }

View on GitHub (pinned to 81131a70a4)