dotnet/wpf · error · NotSupportedException
SR.ReadNotSupported
Error message
SR.ReadNotSupported
What it means
VersionedStreamOwner.EnsureParsed must deserialize the version header from the base stream. If no version was parsed yet, the stream is non-empty, and the stream is not readable (CanRead == false), the file format cannot be validated, so a NotSupportedException is thrown.
Solutions
- Open the underlying stream/package with FileAccess.Read or FileAccess.ReadWrite instead of Write-only.
- Check stream.CanRead before constructing/using the VersionedStreamOwner.
- If the stream is intentionally empty (new file), ensure Length == 0 so the parse path is skipped.
- Wrap access in try-catch for NotSupportedException and surface a clearer 'open with read access' error to users.
Example fix
// before
var stream = new FileStream(path, FileMode.Open, FileAccess.Write);
var vs = new VersionedStreamOwner(stream, ...);
// after
var stream = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
if (!stream.CanRead) throw new InvalidOperationException("Stream must be readable");
var vs = new VersionedStreamOwner(stream, ...); Defensive patterns
Strategy: validation
Validate before calling
public static void EnsureReadable(Stream s, string paramName = "stream")
{
if (s == null) throw new ArgumentNullException(paramName);
if (!s.CanRead && s.Length > 0)
throw new ArgumentException("Stream must be readable to parse an existing compound-file version header", paramName);
} Type guard
bool IsReadableStream(Stream s) => s != null && s.CanRead;
Try / catch
try { owner.ReadAttempt(buffer, 0, len); }
catch (NotSupportedException e) { throw new InvalidDataException("Open the package with read access; the stream is write-only", e); } Prevention
- Always open packages with FileAccess.Read or ReadWrite
- Assert CanRead before constructing packaging streams
- Treat empty (Length == 0) streams as the only write-only-acceptable case
When it happens
Trigger: Opening a VersionedStreamOwner over a non-empty stream opened for write-only access (e.g. FileAccess.Write) and performing WriteAttempt/ReadAttempt/IsUpdatable/IsReadable before any version header is parsed.
Common situations: Opening a package with FileMode.Open/Write-only access and then reading; passing a stream created from a file opened with Write-only permissions; using a network or memory stream that does not support reading.
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
- SR.ReadNotSupported
- ArgumentOutOfRangeException(nameof(offset))
- can’t seek on baseStream
- Read
- SR.PackagingCircularReference
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a6a35e6c36810560.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/VersionedStreamOwner.cs:378
}
/// <summary>
/// Load and compare feature identifier
/// </summary>
/// <remarks>There is no need for this method to maintain any previous Seek pointer.
/// This method only modifies the stream position when called for the first time with a non-empty
/// stream. It is always called from Seek() and set_Position, which subsequently modify the stream
/// pointer as appropriate after the call.</remarks>
private void EnsureParsed()
{
// empty stream cannot have a version in it
if ((_fileVersion == null) && (BaseStream.Length > 0))
{
Debug.Assert(_dataOffset == 0);
// if no version was found and we cannot read from it, then the format is invalid
if (!BaseStream.CanRead)
throw new NotSupportedException(SR.ReadNotSupported);
//
// The physical stream begins with a header that identifies the transform to
// which the stream belongs. The "logical" stream object handed to us by the
// compound file begins -after- this stream header, so when we seek to the
// "beginning" of this stream, we are actually seeking to the location after
// the stream header, where the instance data starts.
//
BaseStream.Seek(0, SeekOrigin.Begin);
//
// The instance data starts with format version information for this transform.
//
_fileVersion = FormatVersion.LoadFromStream(BaseStream);
//
// Ensure that the feature name is as expected.
//View on GitHub (pinned to 81131a70a4)