dotnet/wpf · error · UnauthorizedAccessException

STG_E_ACCESSDENIED

STG_E_ACCESSDENIED

Error message

SR.CanNotCreateAccessDenied

What it means

Thrown by StorageInfo.CreateStorage when the underlying native IStorage.CreateStorage call returns STG_E_ACCESSDENIED. The library translates that HRESULT into UnauthorizedAccessException so callers can distinguish permission problems from other creation failures; the inner COMException preserves the HRESULT.

Solutions

  1. Open the compound file with FileAccess.ReadWrite and FileShare.Read (or none) instead of FileAccess.Read
  2. Ensure the file and directory grant write permission to the current user and the file is not marked read-only
  3. Close other handles locking the file (explorer preview, AV scanner, another app instance)
  4. Copy the package to a writable location before modifying it

Example fix

// before
var root = StorageRoot.OpenOnFile(path, FileMode.Open, FileAccess.Read);
root.CreateSubStorage("newStorage");
// after
var root = StorageRoot.OpenOnFile(path, FileMode.Open, FileAccess.ReadWrite);
root.CreateSubStorage("newStorage");
Defensive patterns

Strategy: try-catch

Validate before calling

var fi = new FileInfo(path);
if (!fi.Exists || fi.IsReadOnly || !CanWrite(path)) throw new UnauthorizedAccessException($"Cannot write to {path}");

Try / catch

try { storage.CreateSubStorage(name); }
catch (UnauthorizedAccessException ex)
{
    var hresult = Marshal.GetHRForException(ex.InnerException as COMException);
    // handle STG_E_ACCESSDENIED: reopen read-write or abort
}

Prevention

When it happens

Trigger: Calling CreateStorage/CreateSubStorage on a compound file opened read-only, on a file locked by another process, or on a location without write permission.

Common situations: Opening an XPS/RM package from a read-only stream or network share, file opened while Windows Search/AV holds it, attempting to modify a package loaded from a Resource or readonly package stream.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/StorageInfo.cs:653

                            nativeCallErrorCode ));
                }
                */
            // It doesn't already exist, please create.
            StorageInfoCore newStorage = core.elementInfoCores[ name ] as StorageInfoCore;
            Invariant.Assert( null != newStorage);
    
            int nativeCallErrorCode = core.safeIStorage.CreateStorage(
                        name, 
                    (GetStat().grfMode & SafeNativeCompoundFileConstants.STGM_READWRITE_Bits)
                        | SafeNativeCompoundFileConstants.STGM_SHARE_EXCLUSIVE,
                    0,
                    0,
                out newStorage.safeIStorage );
            if( SafeNativeCompoundFileConstants.S_OK != nativeCallErrorCode )
            {
                if( nativeCallErrorCode == SafeNativeCompoundFileConstants.STG_E_ACCESSDENIED )
                {
                    throw new UnauthorizedAccessException(
                            SR.CanNotCreateAccessDenied,
                            new COMException( 
                            SR.Format(SR.NamedAPIFailure, "IStorage.CreateStorage"), 
                            nativeCallErrorCode ));
                }
                else
                {
                    throw new IOException(
                        SR.UnableToCreateStorage,
                        new COMException( 
                            SR.Format(SR.NamedAPIFailure, "IStorage.CreateStorage"), 
                            nativeCallErrorCode ));
                }
            }
    
            // Invalidate enumerators
            InvalidateEnumerators();
        }

View on GitHub (pinned to 81131a70a4)