dotnet/wpf · error · ArgumentException

SR.SeekNegative

Error message

SR.SeekNegative

What it means

ArgumentException (SR.SeekNegative) thrown by VersionedStreamOwner.Seek when the computed new position (depending on SeekOrigin.Begin/Current/End plus the offset) is negative — i.e. seeking before the start of the stream data. .NET streams do not allow negative positions, so the call is rejected.

Solutions

  1. Clamp or validate the computed target position to >= 0 before calling Seek
  2. Capture positions with a positive-origin Seek (SeekOrigin.Begin) rather than relative arithmetic
  3. Restore saved positions only on the same stream they were captured from
  4. Use checked arithmetic for offset computations to surface underflow at the right place

Example fix

// before: unguarded relative seek from End
long target = fileLength + delta; // delta may underflow
stream.Seek(target, SeekOrigin.Begin);
// after: clamp to the valid range
long target = Math.Max(0, fileLength + delta);
stream.Seek(target, SeekOrigin.Begin);
Defensive patterns

Strategy: validation

Validate before calling

static long ClampSeek(long origin, long offset, long length) => Math.Max(0, origin switch
{
    SeekOrigin.Begin => offset,
    SeekOrigin.Current => offset,
    SeekOrigin.End => length + offset,
    _ => throw new ArgumentOutOfRangeException(nameof(origin))
});

Try / catch

try
{
    stream.Seek(target, SeekOrigin.Begin);
}
catch (ArgumentException ex) when (ex.Message.Contains("negative"))
{
    logger.LogWarning(ex, "Seek before start of stream; clamping to 0.");
    stream.Seek(0, SeekOrigin.Begin);
}

Prevention

When it happens

Trigger: Calling Seek with a negative offset from SeekOrigin.Begin, or an offset from Current/End large enough that Length+offset < 0 (e.g. Seek(-1000, SeekOrigin.End) on a 100-byte stream). Reached both directly and via the Position setter.

Common situations: Off-by-sign errors when computing relative offsets; saving/restoring a position captured from a different stream; integer underflow when mixing Int32 offsets with long lengths; seeking relative to End on streams assumed larger than they are.

Related errors


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

Appendix: source

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

            long temp = -1;
            switch (origin)
            {
                // seek beyond the FormatVersion
                case SeekOrigin.Begin:
                    temp = offset;
                    break;

                case SeekOrigin.Current:
                    checked { temp = Position + offset; }
                    break;

                case SeekOrigin.End:
                    checked { temp = Length + offset; }
                    break;
            }

            if (temp < 0)
                throw new ArgumentException(SR.SeekNegative);

            checked { BaseStream.Position = temp + _dataOffset; }
            return temp;
        }

        /// <summary>
        /// SetLength
        /// </summary>
        public override void SetLength(long newLength)
        {
            ArgumentOutOfRangeException.ThrowIfNegative(newLength);

            WriteAttempt();
            checked { BaseStream.SetLength(newLength + _dataOffset); }
        }

        /// <summary>
        /// Flush

View on GitHub (pinned to 81131a70a4)