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
- Open the compound file with FileAccess.ReadWrite and FileShare.Read (or none) instead of FileAccess.Read
- Ensure the file and directory grant write permission to the current user and the file is not marked read-only
- Close other handles locking the file (explorer preview, AV scanner, another app instance)
- 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
- Open compound files with FileAccess.ReadWrite when mutating
- Handle STG_E_ACCESSDENIED explicitly to give users a clear message
- Copy read-only packages to a temp writable path before editing
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
- ' ' name is already in use.
- SR.CanNotDeleteInReadOnly
- SR.CanNotDeleteNonEmptyStorage
- SR.CanNotDeleteRoot
- SR.StorageAlreadyExist
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)