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
- Check that offset + current position (for SeekOrigin.Current) or offset alone (for SeekOrigin.Begin) is >= 0 before calling Seek.
- For SeekOrigin.End, clamp the offset so |offset| <= stream length: long safeOffset = Math.Max(offset, -stream.Length);
- Compute the absolute target position with Math.Max(0, target) when negative positions are semantically meaningless for your reader.
- If the negative value comes from parsed package metadata, re-verify/correct the data source; the stream itself is healthy.
- 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
- Compute absolute target positions before seeking and clamp to [0, Length].
- Never feed untrusted parsed lengths directly into Seek offsets.
- Prefer SeekOrigin.Begin with a validated absolute position over relative arithmetic.
- Unit-test edge offsets (Length, -Length, 0) for stream readers.
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
- SeekOrigin value is not valid.
- Stream length cannot be negative.
- ArgumentOutOfRangeException (Parameter 'origin')
- can’t seek on baseStream
- Cannot set seek pointer to a negative position.
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)