AvaloniaUI/Avalonia · error · InvalidOperationException

No suitable cmap subtable found.

Error message

No suitable cmap subtable found.

What it means

A TrueType/OpenType font's 'cmap' table maps Unicode codepoints to glyph indices; without one, text cannot be rendered. GlyphTypeface.LoadCmap walks the table looking for Format 4 (BMP), then Format 13 (last-resort single-glyph), and if neither platform/encoding combination it prefers is present, it gives up. The exception signals the font is structurally valid but lacks any cmap subtable the engine can use.

Source

Thrown at src/Avalonia.Base/Media/Fonts/Tables/Cmap/CmapTable.cs:70

            if (TryFindFormat12Or13Entry(entries, CmapFormat.Format12, out var format12Entry))
            {
                // Prefer Format 12 if available
                return new CharacterToGlyphMap(new CmapFormat12Or13Table(format12Entry.GetSubtableMemory(table)));
            }

            // Then Format 4
            if (TryFindFormat4Entry(entries, out var format4Entry))
            {
                return new CharacterToGlyphMap(new CmapFormat4Table(format4Entry.GetSubtableMemory(table)));
            }

            // Fallback to Format 13, which is a "last resort" format mapping many codepoints to a single glyph
            if (TryFindFormat12Or13Entry(entries, CmapFormat.Format13, out var format13Entry))
            {
                return new CharacterToGlyphMap(new CmapFormat12Or13Table(format13Entry.GetSubtableMemory(table)));
            }

            throw new InvalidOperationException("No suitable cmap subtable found.");

            // Tries to find the best Format 12 subtable entry based on platform and encoding preferences
            static bool TryFindFormat12Or13Entry(CmapSubtableEntry[] entries, CmapFormat expectedFormat, out CmapSubtableEntry result)
            {
                result = default;
                var foundPlatformScore = int.MaxValue;
                var foundEncodingScore = int.MaxValue;

                foreach (var entry in entries)
                {
                    if (entry.Format != expectedFormat)
                    {
                        continue;
                    }

                    var platformScore = entry.Platform switch
                    {
                        PlatformID.Unicode => 0,

View on GitHub (pinned to 11c5427268)

Solutions

  1. Validate the font with a tool (fontTools 'ttx -l', FontForge, or Microsoft Font Validator) and confirm it has a Format 4 subtable with platformID=3/encodingID=1 or a Format 12/13 subtable.
  2. Re-export or subset the font ensuring a Unicode BMP (3,1) Format 4 cmap subtable is included.
  3. Substitute a known-good system font (e.g. an installed Segoe UI / DejaVu Sans) to confirm the GlyphTypeface pipeline works, then bisect back to the failing asset.
  4. If loading untrusted user fonts, catch InvalidOperationException around GlyphTypeface construction and report the asset path rather than crashing.

Example fix

// before
var typeface = new GlyphTypeface(new Uri(assetUri));

// after
GlyphTypeface typeface;
try { typeface = new GlyphTypeface(new Uri(assetUri)); }
catch (InvalidOperationException ex) when (ex.Message.Contains("cmap"))
{
    typeface = new GlyphTypeface(_fallbackSystemFontUri);
    _logger.LogWarning("Asset {Uri} has no usable cmap; falling back. {Err}", assetUri, ex.Message);
}
Defensive patterns

Strategy: fallback

Validate before calling

static bool HasUsableCmap(string fontPath)
{
    try { using var gt = new GlyphTypeface(new Uri(fontPath)); return gt.GlyphCount > 0; }
    catch (InvalidOperationException) { return false; }
}

Try / catch

try { _typeface = new GlyphTypeface(uri); }
catch (InvalidOperationException ex) when (ex.Message.Contains("cmap"))
{
    _typeface = new GlyphTypeface(_systemFallbackUri);
    Log.AssetFontIncompatible(uri, ex.Message);
}

Prevention

When it happens

Trigger: Calling GlyphTypeface on a font file whose cmap only contains Format 0, 1, 2, 6, or other unsupported encodings; a font with cmap entries whose platformID/encodingID do not match the preferred Windows/Unicode scores; a corrupt font whose cmap subtables fail to parse so the filter loop yields nothing.

Common situations: Shipping a legacy Mac-only TrueType font (platformID 1 only); embedding a hand-crafted or stripped font where the toolchain dropped the Unicode BMP (3,1) subtable; reading a CFF/CFF2 OTF that only declares a Format 12 (3,10) subtable but the loop's platform/encoding scoring rejects it; loading a non-font file as a font.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/4472cdb77304f25a. Report an issue: GitHub.