stride3d/stride · error · AssetException

Failed to load font ' ' into msdfgen.

Error message

Failed to load font '{fontSource}' into msdfgen.

What it means

The SignedDistanceFieldFontImporter calls msdfgenLoadFont to hand a font file to the native msdfgen library; when it returns IntPtr.Zero the font could not be parsed/loaded into msdfgen. The importer destroys the msdfgen context, frees FreeType, and throws an AssetException. This means the font file is missing, unreadable, or in a format msdfgen cannot handle.

Solutions

  1. Verify the FontSource path is correct and the file exists relative to the asset (check it is included in the build and copied).
  2. Open the font in another tool (e.g. Windows font viewer, fonttools) to confirm it is a valid TTF/OTF.
  3. Re-download/replace the font with a known-good standard TrueType/OpenType file.
  4. Check build logs above this error for FreeType errors that pinpoint the format problem.

Example fix

// before
FontSource = "fonts/MyFont.ttf", // file not in project
// after
FontSource = "fonts/MyFont-Regular.ttf", // file exists on disk and is included as content
Defensive patterns

Strategy: validation

Validate before calling

var fontPath = UPath.Combine(assetDirectory, asset.FontSource);
if (!File.Exists(fontPath.ToOSPath()))
    throw new FileNotFoundException($"FontSource not found: {fontPath}");
using var fs = File.OpenRead(fontPath.ToOSPath());
if (fs.Length < 4) throw new InvalidDataException("Font file too small to be TTF/OTF");

Type guard

static bool IsValidFontFile(string path) =>
    File.Exists(path) && new FileInfo(path).Length > 100;

Try / catch

try
{
    CompileSdfFont(asset);
}
catch (AssetException ex) when (ex.Message.StartsWith("Failed to load font"))
{
    logger.Error($"Check FontSource '{asset.FontSource}': {ex.Message}");
}

Prevention

When it happens

Trigger: Asset compilation of a spritefont with FontType = SDF (offline rasterized signed distance field) where MsdfgenNative.msdfgenLoadFont returns a null handle for the given fontSource path (e.g. file does not exist, corrupt TTF/OTF, unsupported font format).

Common situations: FontSource path wrong or file deleted from the project; font file with wrong extension or corrupted download; using a font format FreeType/msdfgen cannot parse (e.g. some COLR/CFF2 variable fonts); packaging/copy-to-output rules stripped the .ttf so the path is invalid at build time.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Assets/SpriteFont/Compiler/SignedDistanceFieldFontImporter.cs:64

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

            msdfgenContext = MsdfgenNative.msdfgenContextCreate();
            if (msdfgenContext == IntPtr.Zero)
            {
                FreeTypeNative.FT_Done_FreeType(library);
                throw new InvalidOperationException("Failed to initialize msdfgen context");
            }

            msdfgenFont = MsdfgenNative.msdfgenLoadFont(msdfgenContext, fontSource);
            if (msdfgenFont == IntPtr.Zero)
            {
                MsdfgenNative.msdfgenContextDestroy(msdfgenContext);
                msdfgenContext = IntPtr.Zero;
                FreeTypeNative.FT_Done_FreeType(library);
                throw new AssetException($"Failed to load font '{fontSource}' into msdfgen.");
            }

            try
            {
                var fontData = File.ReadAllBytes(fontSource);
                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 '{fontSource}' (FreeType error {err})");
                    }

                    try

View on GitHub (pinned to 96fad776d2)