dotnet/wpf · error · FileNotFoundException

SR.FileNotFoundExceptionWithFileName

Error message

SR.FileNotFoundExceptionWithFileName

What it means

Util.ThrowWin32Exception maps a Win32 error code from a font-file operation to a strongly typed .NET exception. When errorCode is ERROR_FILE_NOT_FOUND it throws FileNotFoundException with the file name embedded via SR.FileNotFoundExceptionWithFileName.

Solutions

  1. Verify the font file exists at the Uri path (File.Exists) before creating the GlyphTypeface/FontSource.
  2. Correct the font Uri/path, including pack:// syntax for embedded resources.
  3. Ensure embedded font resources have Build Action = Resource and are actually compiled into the assembly.
  4. Check network share availability/permissions if the font resides on a UNC path.

Example fix

// before
var gt = new GlyphTypeface(new Uri(@"C:\Fonts\Missing.ttf"));
// after
string path = @"C:\Fonts\Missing.ttf";
if (!File.Exists(path)) throw new InvalidOperationException($"Font not found: {path}");
var gt = new GlyphTypeface(new Uri(path));
Defensive patterns

Strategy: validation

Validate before calling

string path = fontUri.IsFile ? fontUri.LocalPath : null;
if (path != null && !File.Exists(path))
    throw new InvalidOperationException($"Font file not found: {path}");

Type guard

static bool FontFileExists(Uri fontUri) =>
    fontUri.IsFile && File.Exists(fontUri.LocalPath);

Try / catch

try
{
    var gt = new GlyphTypeface(fontUri);
}
catch (FileNotFoundException ex)
{
    Log($"Font file missing: {ex.FileName}");
    // fall back to a bundled font
}

Prevention

When it happens

Trigger: A font file access API (e.g. FontSource / GlyphTypeface loading a file-based font Uri) failing with Win32 error 2 (ERROR_FILE_NOT_FOUND), routed through Util.ThrowWin32Exception.

Common situations: Font file deleted or moved after the Uri was created; wrong path in a file:// font Uri; font embedded resource not copied to output; network share font unavailable.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

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

        {
            char ca = Char.ToUpperInvariant(a);
            char cb = Char.ToUpperInvariant(b);
            return ca - cb;
        }

        /// <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;

View on GitHub (pinned to 81131a70a4)