stride3d/stride · error · NotSupportedException

Operation 'Seek' is not supported

Error message

Operation 'Seek' is not supported

What it means

LZ4Stream.Seek supports only a narrow set of repositionings: it can seek to position 0 (rewind to the start of the compressed data, resetting decompression state), stay at the current position, or use SeekOrigin.Begin/Current offsets that resolve to those cases. SeekOrigin.End and any other target position throw NotSupportedException ('Seek'), because arbitrary seeking in an LZ4 block stream would require decompressing everything up to that point.

Solutions

  1. Restructure to sequential forward reads only
  2. To rewind, call Seek(0, SeekOrigin.Begin) which is supported (resets the stream)
  3. If random access is required, decompress into a MemoryStream or file first and seek on that
  4. Use SeekOrigin.Current with positive offsets only when the result equals current position or 0

Example fix

// before
lz4.Seek(0, SeekOrigin.End);
// after
lz4.Seek(0, SeekOrigin.Begin); // supported rewind; or decompress fully then seek on the plain stream
Defensive patterns

Strategy: try-catch

Validate before calling

if (origin == SeekOrigin.End) throw new InvalidOperationException("SeekOrigin.End is never supported on LZ4Stream");
if (!(offset == 0 || seekTarget == stream.Position)) throw new InvalidOperationException("LZ4Stream supports only rewind-to-0 and no-op seeks");

Type guard

static bool IsSeekableTarget(long newPosition, long current) => newPosition == 0 || newPosition == current;

Try / catch

try { lz4.Seek(offset, origin); }
catch (NotSupportedException ex) when (ex.Message.Contains("'Seek' is not supported")) { // fallback: decompress fully, then seek on plain stream
  var ms = new MemoryStream(); lz4.CopyTo(ms); ms.Position = 0; ms.Seek(offset, origin); }

Prevention

When it happens

Trigger: Calling Seek(offset, SeekOrigin.End); calling Seek to a nonzero destination other than the current position; library code that assumes seekable streams (e.g. serializers doing backtracking).

Common situations: Deserializers seeking back to fix up lengths; code using SeekOrigin.End to compute stream length; random-access reads over LZ4-compressed data.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/6a3f8367f0e7c698. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core.Serialization/Serialization/LZ4/LZ4Stream.cs:437

            }
            else
            {
                if (!AcquireNextChunk()) break;
            }
        }
        position += total;

        return total;
    }

    /// <inheritdoc/>
    public override long Seek(long offset, SeekOrigin origin)
    {
        var newPosition = origin switch
        {
            SeekOrigin.Begin => offset,
            SeekOrigin.Current => Position + offset,
            SeekOrigin.End => throw NotSupported("Seek"),
            _ => throw new ArgumentOutOfRangeException(nameof(origin)),
        };
        if (newPosition == 0)
        {
            innerStream.Seek(-innerStreamPosition, SeekOrigin.Current);
            Reset();
        }
        else if (newPosition == Position)
        {
            // nothing to do
        }
        else
        {
            throw NotSupported("Seek");
        }

        return Position;
    }

View on GitHub (pinned to 96fad776d2)