dotnet/wpf · error · UnauthorizedAccessException

SR.UnauthorizedAccessExceptionWithFileName

Error message

SR.UnauthorizedAccessExceptionWithFileName

What it means

Resource-formatted PathTooLongException produced by FontCacheUtil.ThrowWin32Exception: when the Win32 error for a path exceeding MAX_PATH is returned while opening a font file for reading, it is translated into a PathTooLongException whose message includes the offending file name.

Solutions

  1. Grant the running user read access (ACLs) to the font file/directory.
  2. Copy the font into an application-accessible location (app directory or app data) and reference it there.
  3. Run under an account with sufficient permissions, or elevate if appropriate.
  4. For system fonts, reference them via installed-font family APIs instead of opening the file directly.

Example fix

// before
var gt = new GlyphTypeface(new Uri(@"C:\Windows\Fonts\Restricted.ttf")); // access denied
// after
string dest = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Fonts", "MyFont.ttf");
var gt = new GlyphTypeface(new Uri(dest)); // font shipped with app, readable
Defensive patterns

Strategy: try-catch

Validate before calling

try { using var _ = File.OpenRead(fontUri.LocalPath); }
catch (UnauthorizedAccessException) { /* copy font to app dir or adjust ACLs first */ }

Try / catch

try
{
    var gt = new GlyphTypeface(fontUri);
}
catch (UnauthorizedAccessException)
{
    // fall back to an app-local copy of the font
    var gt = new GlyphTypeface(new Uri(appLocalFontPath));
}

Prevention

When it happens

Trigger: Opening a font source where the OS denies access (Win32 error 5) — e.g. font in a protected directory (C:\Windows\Fonts opened without rights, Program Files, another user's profile).

Common situations: Running the app without elevation while the font file has restrictive ACLs; fonts installed per-user in another account's profile; corporate-locked font directories; antivirus/ACL restrictions.

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/8d16302831b92034. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontCacheUtil.cs:754

        /// <summary>
        /// This function performs job similar to CLR's internal __Error.WinIOError function:
        /// it maps win32 errors from file I/O to CLR exceptions and includes string where possible.
        /// However, we're interested only in errors when opening a file for reading.
        /// </summary>
        /// <param name="errorCode">Win32 error code.</param>
        /// <param name="fileName">File name string.</param>
        internal static void ThrowWin32Exception(int errorCode, string fileName)
        {
            switch (errorCode)
            {
                case NativeMethods.ERROR_FILE_NOT_FOUND:
                    throw new FileNotFoundException(SR.Format(SR.FileNotFoundExceptionWithFileName, fileName), fileName);

                case NativeMethods.ERROR_PATH_NOT_FOUND:
                    throw new DirectoryNotFoundException(SR.Format(SR.DirectoryNotFoundExceptionWithFileName, fileName));

                case NativeMethods.ERROR_ACCESS_DENIED:
                    throw new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccessExceptionWithFileName, fileName));

                case NativeMethods.ERROR_FILENAME_EXCED_RANGE:
                    throw new PathTooLongException(SR.Format(SR.PathTooLongExceptionWithFileName, fileName));

                default:
                    throw new IOException(SR.Format(SR.IOExceptionWithFileName, fileName), NativeMethods.MakeHRFromErrorCode(errorCode));
            }
        }

        internal static Exception ConvertInPageException(FontSource fontSource, SEHException e)
        {
            string fileName;
            if (fontSource.IsFile)
            {
                fileName = fontSource.Uri.LocalPath;
            }
            else
            {

View on GitHub (pinned to 81131a70a4)