stride3d/stride · error · InvalidOperationException

Failed to load glyph for character

Error message

Failed to load glyph for character '{character}' (FreeType error {err})

What it means

In ImportGlyph, FT_Load_Glyph fails for a specific character (non-zero FreeType error code), so the importer throws this InvalidOperationException. The glyph outline for that character could not be retrieved from the loaded font face.

Solutions

  1. Remove the problematic character(s) from the character set of the sprite font asset.
  2. Try a different version of the font file known to be intact.
  3. Re-export/convert the font (e.g. with fontforge) to fix a damaged glyf table.
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    importer.ImportGlyph(character, glyphIndex);
}
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Failed to load glyph"))
{
    log.Warn($"Skipping character '{character}': {ex.Message}");
}

Prevention

When it happens

Trigger: FT_Load_Glyph returns an error for the glyph index of a character being compiled - e.g. invalid glyph index, corrupted face, or unsupported font data mid-import.

Common situations: Fonts with damaged character-map entries; characters mapping to invalid glyph indices; memory pressure while processing large character sets.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

                var emptyBitmap = new Image<Rgba32>(1, 1);
                var glyph = new Glyph(character, emptyBitmap)
                {
                    XOffset = 0,
                    YOffset = 0,
                    XAdvance = glyphIndex != 0 ? face->glyph->advance.x.Value / 64.0f : 0,
                };
                return glyph;
            }

            // Load and render the glyph
            {
                var loadTarget = antiAliasMode == FontAntiAliasMode.Aliased
                    ? FreeTypeLoadTarget.Mono
                    : FreeTypeLoadTarget.Normal;
                int err = FreeTypeNative.FT_Load_Glyph(face, glyphIndex, (int)FreeTypeLoadFlags.Default | (int)loadTarget);
                if (err != 0)
                    throw new InvalidOperationException($"Failed to load glyph for character '{character}' (FreeType error {err})");

                var renderMode = antiAliasMode == FontAntiAliasMode.Aliased
                    ? FreeTypeRenderMode.Mono
                    : FreeTypeRenderMode.Normal;
                err = FreeTypeNative.FT_Render_Glyph(face->glyph, renderMode);
                if (err != 0)
                    throw new InvalidOperationException($"Failed to render glyph for character '{character}' (FreeType error {err})");
            }

            ref FT_Bitmap ftBitmap = ref face->glyph->bitmap;
            int width = (int)ftBitmap.width;
            int height = (int)ftBitmap.rows;

            if (width == 0 || height == 0)
            {
                var emptyBitmap = new Image<Rgba32>(1, 1);
                return new Glyph(character, emptyBitmap)
                {

View on GitHub (pinned to 96fad776d2)