dotnet/wpf · error · ArgumentException

SR.SeekNegative

Error message

SR.SeekNegative

What it means

CompressEmulationStream.Seek throws ArgumentOutOfRangeException when the computed new position is negative. After resolving the offset relative to Begin/Current/End, a resulting position below zero is invalid for a stream and the seek is rejected.

Solutions

  1. Clamp or validate the computed offset so it is >= 0 before calling Seek.
  2. Use SeekOrigin.Current only when you know the current position plus offset is non-negative.
  3. Store positions with long and check before seeking.

Example fix

// before
stream.Seek(-(headerSize + extra), SeekOrigin.Current);
// after
long target = stream.Position - (headerSize + extra);
if (target < 0) target = 0;
stream.Seek(target, SeekOrigin.Begin);
Defensive patterns

Strategy: validation

Validate before calling

long ComputeSeekTarget(long current, long length, long offset, SeekOrigin origin)
{
    long target = origin switch
    {
        SeekOrigin.Begin => offset,
        SeekOrigin.Current => current + offset,
        SeekOrigin.End => length + offset,
        _ => throw new ArgumentOutOfRangeException(nameof(origin))
    };
    if (target < 0) throw new ArgumentException("Seek target is negative", nameof(offset));
    return target;
}

Type guard

bool IsValidSeek(long current, long length, long offset, SeekOrigin origin) =>
    (origin == SeekOrigin.Begin ? offset :
     origin == SeekOrigin.Current ? current + offset : length + offset) >= 0;

Try / catch

try { es.Seek(offset, SeekOrigin.Current); }
catch (ArgumentException) { es.Seek(0, SeekOrigin.Begin); }

Prevention

When it happens

Trigger: Seek(offset, SeekOrigin.Begin) or Current with a negative resulting position — e.g. Seek(-10, SeekOrigin.Begin) or a large negative offset relative to Current — invoked via Position or directly.

Common situations: Off-by-one buffer math, subtracting more than the bytes read from Current, rewinding before position 0 when parsing headers.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompressEmulationStream.cs:93

                case SeekOrigin.Current:
                    {
                        checked { temp = _tempStream.Position + offset; }
                        break;
                    }
                case SeekOrigin.End:
                    {
                        checked { temp = _tempStream.Length + offset; }
                        break;
                    }
                default:
                    {
                        throw new ArgumentOutOfRangeException(nameof(origin), SR.SeekOriginInvalid);
                    }
            }

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

            return _tempStream.Seek(offset, origin);
        }

        /// <summary>
        /// SetLength
        /// </summary>
        public override void SetLength(long newLength)
        {
            CheckDisposed();

            _tempStream.SetLength(newLength);

            // truncation always involves change of stream pointer
            if (newLength < _tempStream.Position)
                _tempStream.Position = newLength;

View on GitHub (pinned to 81131a70a4)