AvaloniaUI/Avalonia · error · InvalidOperationException

No cmap table found.

Error message

No cmap table found.

What it means

CmapTable.Load throws InvalidOperationException when the font's platform typeface has no 'cmap' table. The cmap table maps character codes (Unicode) to glyph indices and is essential for text rendering — a font without it cannot be used for character-to-glyph mapping. This is an internal API typically reached during GlyphTypeface construction.

Source

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

namespace Avalonia.Media.Fonts.Tables.Cmap
{
    /// <summary>
    /// Represents the 'cmap' table in an OpenType font, which maps character codes to glyph indices.
    /// </summary>
    /// <remarks>The 'cmap' table is a critical component of an OpenType font, enabling the mapping of
    /// character codes (e.g., Unicode) to glyph indices used for rendering text. This class provides functionality to
    /// load and parse the 'cmap' table from a font's platform-specific typeface.</remarks>
    internal sealed class CmapTable
    {
        internal const string TableName = "cmap";
        internal static OpenTypeTag Tag { get; } = OpenTypeTag.Parse(TableName);

        public static CharacterToGlyphMap Load(GlyphTypeface glyphTypeface)
        {
            if (!glyphTypeface.PlatformTypeface.TryGetTable(Tag, out var table))
            {
                throw new InvalidOperationException("No cmap table found.");
            }

            var reader = new BigEndianBinaryReader(table.Span);

            reader.ReadUInt16(); // version

            var numTables = reader.ReadUInt16();

            var entries = new CmapSubtableEntry[numTables];

            for (var i = 0; i < numTables; i++)
            {
                var platformID = (PlatformID)reader.ReadUInt16();
                var encodingID = (CmapEncoding)reader.ReadUInt16();
                var offset = (int)reader.ReadUInt32();

                var position = reader.Position;

View on GitHub (pinned to 11c5427268)

Solutions

  1. Use a valid, standard TrueType/OpenType font that includes a cmap table (verify with a font inspector like FontForge).
  2. If loading from a stream/resource, verify the data is complete and not truncated.
  3. Catch the exception at font-loading boundaries and fall back to a known-good system font.
  4. For custom font collections, ensure each face exposes a cmap subtable.

Example fix

// before
var typeface = new GlyphTypeface(new Uri("avares://App/Assets/brokenfont.ttf"));

// after
GlyphTypeface typeface;
try
{
    typeface = new GlyphTypeface(new Uri("avares://App/Assets/myfont.ttf"));
}
catch (InvalidOperationException)
{
    typeface = new GlyphTypeface(new Uri("avares://App/Assets/fallback.ttf"));
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the font has a cmap table before constructing a GlyphTypeface
// (no public pre-check exists; validate the source file with a font library, or catch):

Try / catch

GlyphTypeface typeface;
try
{
    typeface = new GlyphTypeface(fontUri);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("cmap"))
{
    typeface = new GlyphTypeface(fallbackFontUri);
}

Prevention

When it happens

Trigger: Loading a GlyphTypeface from a font file/stream that lacks a 'cmap' table. Happens with malformed fonts, some legacy/symbol fonts, bitmap-only fonts, or truncated/corrupt font data. Reached internally when the font manager creates a typeface for rendering.

Common situations: Bundling a corrupt or non-standard font file. Using a bitmap-only font (FON/FNT) that has no cmap. A truncated download of a font resource. A font file that is actually a collection where the selected face lacks cmap. Embedding a font in avares: that got damaged.

Related errors


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