dotnet/wpf · error · InvalidOperationException
SR.SeekNotSupported
Error message
SR.SeekNotSupported
What it means
The CompressEmulationStream constructor requires the base stream to support seeking, because emulating compression on top of it needs both seek and read. A non-seekable base stream causes an InvalidOperationException with SR.SeekNotSupported.
Solutions
- Buffer the base stream into a seekable medium first (MemoryStream or FileStream) before constructing.
- Check baseStream.CanSeek before constructing and fail with a clear message.
- For network sources, download to a temp file and open that.
Example fix
// before
var es = new CompressEmulationStream(networkStream, tempStream, transformer);
// after
if (!networkStream.CanSeek)
{
var buffered = new MemoryStream();
networkStream.CopyTo(buffered);
buffered.Position = 0;
networkStream = buffered;
}
var es = new CompressEmulationStream(networkStream, tempStream, transformer); Defensive patterns
Strategy: validation
Validate before calling
static Stream AsSeekable(Stream source)
{
if (source.CanSeek) return source;
var ms = new MemoryStream();
source.CopyTo(ms);
ms.Position = 0;
return ms;
} Type guard
bool IsSeekableReadable(Stream s) => s != null && s.CanSeek && s.CanRead;
Try / catch
try { var es = new CompressEmulationStream(baseStream, tempStream, transformer); }
catch (InvalidOperationException e) { throw new InvalidDataException("Base stream must be seekable and readable; buffer it first", e); } Prevention
- Buffer network/pipe streams into MemoryStream or a temp file before emulating
- Check CanSeek before constructing
- Prefer opening packages over local files
When it happens
Trigger: Constructing CompressEmulationStream with a baseStream whose CanSeek is false — e.g. a network stream, a forward-only decompressed stream, or a write-only FileStream.
Common situations: Wrapping HTTP response streams or pipes; opening packages directly over non-seekable sources; forwarding a stream from a download before buffering it.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- can’t seek on baseStream
- ArgumentOutOfRangeException(nameof(offset))
- SR.ParserWriterNoSeekEnd
- SR.ParserWriterUnknownOrigin
- SR.ReadNotSupported
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/2220d6b040c889a3.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompressEmulationStream.cs:254
/// <summary>
/// Constructor
/// </summary>
/// <param name="baseStream">part stream - not closed - caller determines lifetime</param>
/// <param name="position">current logical stream position</param>
/// <param name="tempStream">should be an IsolatedStorageFileStream - not closed - caller determines lifetime</param>
/// <param name="transformer">class that does the compression/decompression</param>
/// <remarks>This class should only invoked when emulation is required.
/// Does not close any given stream, even when Close is called. This means that it requires
/// another wrapper Stream class.</remarks>
internal CompressEmulationStream(Stream baseStream, Stream tempStream, long position, IDeflateTransform transformer)
{
ArgumentOutOfRangeException.ThrowIfNegative(position);
ArgumentNullException.ThrowIfNull(baseStream);
// seek and read required for emulation
if (!baseStream.CanSeek)
throw new InvalidOperationException(SR.SeekNotSupported);
if (!baseStream.CanRead)
throw new InvalidOperationException(SR.ReadNotSupported);
ArgumentNullException.ThrowIfNull(tempStream);
ArgumentNullException.ThrowIfNull(transformer);
_baseStream = baseStream;
_tempStream = tempStream;
_transformer = transformer;
// extract to temporary stream
_baseStream.Position = 0;
_tempStream.Position = 0;
_transformer.Decompress(baseStream, tempStream);
// seek to the current logical position
_tempStream.Position = position;View on GitHub (pinned to 81131a70a4)