dotnet/wpf · error · IOException

SR.UnableToCreateOnStream

Error message

SR.UnableToCreateOnStream

What it means

StorageRoot.CreateOnStream failed to create a compound file container on the given Stream: the underlying StgCreateStorageEx-on-stream call returned a failure HRESULT other than S_OK. The library wraps the HRESULT in a COMException and surfaces it as an IOException because the compound file could not be initialized on the supplied stream.

Solutions

  1. Ensure the Stream supports Read, Write and Seek (CanRead/CanWrite/CanSeek all true) before creating the package.
  2. Check the inner COMException's HResult to identify the native failure and fix the root cause (permissions, stream state).
  3. Verify the stream is open (not disposed) for the lifetime of the package.
  4. If creating on disk is acceptable, use the path-based Package.Open overload instead of a stream.

Example fix

// before
var pkg = Package.Open(closedOrReadOnlyStream, FileMode.Create);
// after
if (!stream.CanRead || !stream.CanWrite || !stream.CanSeek)
    stream = new MemoryStream();
var pkg = Package.Open(stream, FileMode.Create, FileAccess.ReadWrite);
Defensive patterns

Strategy: validation

Validate before calling

if (stream == null) throw new ArgumentNullException(nameof(stream));
if (!stream.CanRead || !stream.CanWrite || !stream.CanSeek)
    throw new ArgumentException("Stream must be readable, writable and seekable", nameof(stream));

Type guard

bool IsValidPackageStream(Stream s) => s != null && s.CanRead && s.CanWrite && s.CanSeek;

Prevention

When it happens

Trigger: Calling System.IO.Packaging.StorageRoot.CreateOnStream (indirectly via Package.Open on a stream with Create mode) when the native compound-file API returns an error, e.g. the stream does not support Read/Write/Seek as required, or the stream is closed/disposed.

Common situations: Passing a non-seekable or write-protected stream to Package.Open; using a MemoryStream already closed; opening a package on a stream over a read-only file while requesting Create mode.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/StorageRoot.cs:160

            returnValue = SafeNativeCompoundFileMethods.SafeStgOpenStorageOnStream(
                baseStream,
                openFlags,
                out storageOnStream );
        }
        else
        {
            throw new ArgumentException(
                SR.CreateModeMustBeCreateOrOpen);
        }
        
        switch( (uint) returnValue )
        {
            case SafeNativeCompoundFileConstants.S_OK:
                return StorageRoot.CreateOnIStorage( 
                    storageOnStream );

            default:
                throw new IOException(
                    SR.UnableToCreateOnStream,
                    new COMException(
                        SR.CFAPIFailure, 
                        returnValue));
        }
    }

    /// <summary>Open a container, given only the path.</summary>
    /// <param name="path">Path to container file on local file system</param>
    /// <returns>StorageRoot instance representing the file</returns>
    internal static StorageRoot Open( 
        string path )
    {
        return Open( path, defaultFileMode, defaultFileAccess, defaultFileShare, defaultSectorSize );
    }

    /// <summary>Open a container, given path and open mode</summary>
    /// <param name="path">Path to container file on local file system</param>

View on GitHub (pinned to 81131a70a4)