stride3d/stride · error · InvalidOperationException

Failed to load font ' ' (FreeType error )

Error message

Failed to load font '{fontPath}' (FreeType error {err})

What it means

LoadFontInMemory (invoked via GetOrCreateFontFace) passes a byte buffer to FT_New_Memory_Face; a nonzero result means FreeType rejected the embedded font data. The thrown InvalidOperationException names the font path and FreeType error code, and frees the pinned handle before throwing.

Solutions

  1. Confirm the bytes handed to the loader are the complete font file (compare hash with the source file)
  2. Regenerate the embedded font resource; check the build task that embeds it
  3. Match the FreeType error code in the message against FreeType error enums to pinpoint format issues
  4. Clear any cached font data/cache files so a corrupt cache entry is rebuilt
Defensive patterns

Strategy: validation

Validate before calling

if (fontBytes == null || fontBytes.Length < 12)
    throw new InvalidDataException("Embedded font data is missing or truncated");

Try / catch

try { face = GetOrCreateFontFace(fontPath); }
catch (InvalidOperationException ex) when (ex.Message.Contains("FreeType error"))
{
    log.Error($"Failed to create font face for {fontPath}", ex);
    face = GetOrCreateFontFace(DefaultFontPath);
}

Prevention

When it happens

Trigger: GetOrCreateFontFace resolving a font whose loaded byte data is invalid: corrupted embedded font resource, wrong index/data slice, or data that FreeType cannot parse as a face.

Common situations: Embedded font resources corrupted during build (bad resx/embedded-resource step); passing a non-font stream (e.g. a license txt) to a runtime font loader; partial writes to a font cache file that is later reloaded.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/615b3cb191b4f89c. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Font/FontManager.cs:349

                fontStream.ReadExactly(fontData);

                var handle = GCHandle.Alloc(fontData, GCHandleType.Pinned);
                lock (freetypeLock)
                {
                    // Double-check inside lock
                    if (cachedFontFaces.ContainsKey(fontPath))
                    {
                        handle.Free();
                        return;
                    }

                    fixed (byte* ptr = fontData)
                    {
                        int err = FreeTypeNative.FT_New_Memory_Face(freetypeLibrary, ptr, new CLong(fontData.Length), new CLong(0), out FT_FaceRec* face);
                        if (err != 0)
                        {
                            handle.Free();
                            throw new InvalidOperationException($"Failed to load font '{fontPath}' (FreeType error {err})");
                        }
                        cachedFontFaces[fontPath] = ((nint)face, handle);
                    }
                }
            }
        }

        /// <summary>
        /// Thread function in charge of building the bitmap
        /// </summary>
        private void BuildBitmapThread()
        {
            while (!bitmapShouldEndThread)
            {
                bitmapBuildSignal.WaitOne();

                while (bitmapsToGenerate.Count > 0)
                {

View on GitHub (pinned to 96fad776d2)