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
- Verify the FontSource path is correct and the file exists relative to the asset (check it is included in the build and copied).
- Open the font in another tool (e.g. Windows font viewer, fonttools) to confirm it is a valid TTF/OTF.
- Re-download/replace the font with a known-good standard TrueType/OpenType file.
- 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
- Include font files in the project and verify copy-to-output/content settings
- Validate fonts with fonttools or a viewer before committing them
- Use relative, package-rooted FontSource paths and check them after refactoring
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
- Failed to load font ' ' (FreeType error )
- Could not locate native executable
- Could not locate native library
- Failed to initialize FreeType library
- Failed to load font ' ' (FreeType error )
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})");
}
tryView on GitHub (pinned to 96fad776d2)