dotnet/wpf · error · IOException
Read
Error message
Read
What it means
UnsafeIndexingFilterStream.Read reads through an unmanaged IStream (_oleStream) exposed by a COM IFilter. If the underlying OLE stream throws COMException, or a nested IOException occurs, the stream restores Position to the pre-read value and rethrows as a bare IOException with message "Read" and the original exception as InnerException. The real cause is always in InnerException.
Solutions
- Inspect the InnerException (COMException) of the IOException for the actual HRESULT and failure reason.
- Validate/repair the package file before opening the indexing filter stream.
- Retry reading after the stream auto-rewinds Position, if the source is intermittently failing.
- Catch IOException and fall back to reading the part via System.IO.Packaging APIs instead of the filter stream.
Example fix
// before
int n = filterStream.Read(buffer, 0, buffer.Length);
// after
try
{
int n = filterStream.Read(buffer, 0, buffer.Length);
}
catch (IOException ex) when (ex.InnerException is COMException cex)
{
// inspect cex.ErrorCode for the real HRESULT
} Defensive patterns
Strategy: try-catch
Validate before calling
// before reading
if (filterStream == null || !filterStream.CanRead)
throw new InvalidOperationException("Filter stream not readable"); Try / catch
try { int n = filterStream.Read(buffer, 0, count); }
catch (IOException ex)
{
// Position was auto-restored; log ex.InnerException (often COMException with HRESULT)
throw new IOException("Indexing filter read failed", ex);
} Prevention
- Always read ex.InnerException to learn the real HRESULT/cause.
- Verify the package file is valid and fully downloaded before indexing.
- Keep the source stream open for the filter stream's whole lifetime.
- Use the auto-restored Position to safely retry reads.
When it happens
Trigger: Calling Stream.Read on an UnsafeIndexingFilterStream when the underlying _oleStream.Read COM call fails (corrupt or non-seekable source stream, filter error) or an inner IOException propagates.
Common situations: Indexing/searching a damaged or partially downloaded XPS/OPC package; the filter's stream fails mid-read; callers that inspect only ex.Message see the useless string "Read" and miss the COMException details.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- SR.ReadNotSupported
- SR.ReadNotSupported
- A read or write operation references a location outside the…
- ArgumentOutOfRangeException(nameof(offset))
- ArgumentOutOfRangeException: offset is outside the valid…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/770aef0d968edd79.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/IO/Packaging/UnsafeIndexingFilterStream.cs:110
// Prepare location of return value and call the COM object.
int bytesRead;
IntPtr pBytesRead = new IntPtr(&bytesRead);
// Prepare to restore position in case the read fails.
long positionBeforeReadAttempt = this.Position;
try
{
// Pin the array wrt GC while using an address in it.
fixed (byte *bufferPointer = &buffer[offset])
{
_oleStream.Read(new IntPtr(bufferPointer), count, pBytesRead);
}
}
catch (COMException comException)
{
this.Position = positionBeforeReadAttempt;
throw new IOException("Read", comException);
}
catch (IOException ioException)
{
this.Position = positionBeforeReadAttempt;
throw new IOException("Read", ioException);
}
return bytesRead;
}
/// <summary>
/// Seek -unmanaged streams do not allow seeking beyond the end of the stream
/// and since we rely on the underlying stream to validate and return the seek
/// results, unlike managed streams where seeking beyond the end of the stream
/// is allowed we will get an exception.
/// </summary>
/// <param name="offset">Offset in byte.</param>
/// <param name="origin">Offset origin (start, current, or end).</param>
public override unsafe long Seek(long offset, SeekOrigin origin)View on GitHub (pinned to 81131a70a4)