stride3d/stride · error · FileNotFoundException

Font file not found

Error message

Font file not found: {fontPath}

What it means

After FreeType initializes, FreeTypeFontImporter.Import resolves the font source path and throws FileNotFoundException when the path is null/empty or the file does not exist. It guards the TrueType/OpenType file that will be pinned in memory for FT_New_Memory_Face.

Solutions

  1. Verify the font path exists: File.Exists(options.FontSource.GetFontPath()); fix FontSource in the asset.
  2. Re-import or re-add the .ttf/.otf file to the project.
  3. Restore the missing font file from source control or reinstall the font.

Example fix

// before
Source = "C:/Windows/Fonts/oldfont.ttf";

// after
Source = "assets/fonts/Inter-Regular.ttf"; // file exists in project
Defensive patterns

Strategy: validation

Validate before calling

var fontPath = fontAsset.FontSource.GetFontPath();
if (string.IsNullOrEmpty(fontPath) || !File.Exists(fontPath))
    throw new FileNotFoundException($"Font file not found: {fontPath}");

Try / catch

catch (FileNotFoundException ex) { log.Error($"Restore font file: {ex.FileName}"); }

Prevention

When it happens

Trigger: SpriteFontAsset.FontSource.GetFontPath() returns a nonexistent or empty path when compiling an offline-rasterized (system/OTF/TTF) font.

Common situations: Font file deleted or renamed after the .sdfont was created; relative path broken by moving the project; missing font file in source control.

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 stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/7fbd6dad35ca4eca. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Assets/SpriteFont/Compiler/FreeTypeFontImporter.cs:40

        public IEnumerable<Glyph> Glyphs { get; private set; }

        public float LineSpacing { get; private set; }

        public float BaseLine { get; private set; }

        public void Import(SpriteFontAsset options, List<char> characters)
        {
            NativeLibraryHelper.PreloadLibrary("freetype", typeof(FreeTypeFontImporter));

            int err = FreeTypeNative.FT_Init_FreeType(out var library);
            if (err != 0)
                throw new InvalidOperationException($"Failed to initialize FreeType library (error {err})");

            try
            {
                var fontPath = options.FontSource.GetFontPath();
                if (string.IsNullOrEmpty(fontPath) || !File.Exists(fontPath))
                    throw new FileNotFoundException($"Font file not found: {fontPath}");

                var fontData = File.ReadAllBytes(fontPath);
                var handle = GCHandle.Alloc(fontData, GCHandleType.Pinned);

                try
                {
                    FT_FaceRec* face;
                    fixed (byte* ptr = fontData)
                    {
                        err = FreeTypeNative.FT_New_Memory_Face(library, ptr, new CLong(fontData.Length), new CLong(0), out face);
                        if (err != 0)
                            throw new InvalidOperationException($"Failed to load font '{fontPath}' (FreeType error {err})");
                    }

                    try
                    {
                        var fontSize = options.FontType.Size;

View on GitHub (pinned to 96fad776d2)