stride3d/stride · error · InvalidOperationException
Failed to load font ' ' (FreeType error )
Error message
Failed to load font '{fontPath}' (FreeType error {err}) What it means
FreeTypeFontImporter.Import loads the font bytes with FT_New_Memory_Face; if FreeType returns a non-zero error code the importer throws this InvalidOperationException. It means FreeType could not parse the font data as a valid font face (the file existed but is invalid/unsupported).
Solutions
- Verify the font file is a valid, uncorrupted TTF/OTF (open it in a font viewer).
- Re-download or re-export the font file; avoid truncated copies.
- Try a different static font file; some variable/restricted fonts fail to load.
Defensive patterns
Strategy: validation
Validate before calling
var bytes = File.ReadAllBytes(fontPath);
if (bytes.Length < 4 ||
!(bytes[0] == 0x00 && bytes[1] == 0x01 && bytes[2] == 0x00 && bytes[3] == 0x00) &&
!System.Text.Encoding.ASCII.GetString(bytes, 0, 4).Contains("OTTO"))
throw new InvalidDataException("Not a valid TTF/OTF file"); Try / catch
catch (InvalidOperationException ex) when (ex.Message.Contains("FreeType error")) { log.Error($"Invalid font data: {ex.Message}"); } Prevention
- Verify fonts open in a font viewer before adding them to assets.
- Avoid truncated downloads; checksum font files.
When it happens
Trigger: Passing a corrupt, truncated, or non-font file (wrong format, DRM-protected font, HTML error page saved as .ttf) to FT_New_Memory_Face during sprite font compilation.
Common situations: Misnamed file extensions (e.g. an OTF variable font variant unsupported by the bundled FreeType); partial downloads; wrong file selected in the FontSource picker.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Failed to initialize FreeType library
- Failed to load glyph for character
- Failed to render glyph for character
- The decimalPlaces should be greater or equal to zero.
- The minimum should be lesser or equal to the maximum.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/e882f69b427ac85a.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Assets/SpriteFont/Compiler/FreeTypeFontImporter.cs:52
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;
// Set font size: 26.6 fixed-point, 72 dpi so size is in pixels
var charSize = new CLong((int)(fontSize * 64));
FreeTypeNative.FT_Set_Char_Size(face, charSize, charSize, 72, 72);
// Compute line spacing and baseline using FreeType metrics
// These are in font units — convert to pixels
float unitsToPixels = fontSize / face->units_per_EM;
var lineGap = (face->height - face->ascender + face->descender) * options.LineGapFactor;
LineSpacing = (lineGap + face->ascender - face->descender) * unitsToPixels;
BaseLine = (lineGap * options.LineGapBaseLineFactor + face->ascender) * unitsToPixels;
var glyphList = new List<Glyph>();View on GitHub (pinned to 96fad776d2)