d2lang/d2 · error

failed to encode ttf to woff: %v

Error message

failed to encode ttf to woff: %v

What it means

AddFontStyle stores the raw TTF in the FontFaces cache, then converts it to WOFF via fontlib.Sfnt2Woff for embedding as a base64 data URI. When the TTF bytes cannot be parsed/encoded as an SFNT font, it wraps and returns this error.

Source

Thrown at d2renderers/d2fonts/d2fonts_common.go:121

	HandDrawn,
}

var FontFamiliesMu sync.Mutex

var FontEncodings syncmap.SyncMap[Font, string]
var FontFaces syncmap.SyncMap[Font, []byte]

var D2_FONT_TO_FAMILY = map[string]FontFamily{
	"default": SourceSansPro,
	"mono":    SourceCodePro,
}

func AddFontStyle(font Font, style FontStyle, ttf []byte) error {
	FontFaces.Set(font, ttf)

	woff, err := fontlib.Sfnt2Woff(ttf)
	if err != nil {
		return fmt.Errorf("failed to encode ttf to woff: %v", err)
	}
	encodedWoff := fmt.Sprintf("data:application/font-woff;base64,%v", base64.StdEncoding.EncodeToString(woff))
	FontEncodings.Set(font, encodedWoff)

	return nil
}

func AddFontFamily(name string, regularTTF, italicTTF, boldTTF, semiboldTTF []byte) (*FontFamily, error) {
	FontFamiliesMu.Lock()
	defer FontFamiliesMu.Unlock()
	customFontFamily := FontFamily(name)

	regularFont := Font{
		Family: customFontFamily,
		Style:  FONT_STYLE_REGULAR,
	}
	if regularTTF != nil {
		err := AddFontStyle(regularFont, FONT_STYLE_REGULAR, regularTTF)

View on GitHub (pinned to 0d69dca6f5)

Solutions

  1. Verify the font file is a real TTF (TrueType) file — check the first 4 bytes are 0x00010000 or 'true'/'OTTO' as supported
  2. Re-download/re-export the font; do not pass WOFF/WOFF2 files where TTF is expected
  3. Convert the font to plain TTF (e.g. with fonttools: ttx/flat conversion) before calling AddFontStyle
  4. Check the path/read call that produced the ttf []byte for empty or truncated content

Example fix

// before
d2fonts.AddFontStyle(font, style, readBytes("logo.woff"))
// after
ttfBytes := convertToTTF(readBytes("logo.woff")) // e.g. via fonttools
err := d2fonts.AddFontStyle(font, style, ttfBytes)
Defensive patterns

Strategy: validation

Validate before calling

if len(ttf) < 4 {
	return errors.New("font file too small to be a TTF")
}
tag := binary.BigEndian.Uint32(ttf[:4])
if tag != 0x00010000 && tag != 0x74727565 && tag != 0x4F54544F {
	return errors.New("not a valid TTF/OTF file")
}

Try / catch

if err := d2fonts.AddFontStyle(font, style, ttf); err != nil {
	if strings.Contains(err.Error(), "failed to encode ttf to woff") {
		// fall back to default font
	}
}

Prevention

When it happens

Trigger: Calling d2fonts.AddFontStyle (or AddFontFamily, which delegates) with ttf bytes that are not a valid TTF/OTF (e.g. already-WOFF data, truncated download, HTML error page bytes).

Common situations: Loading a custom font whose file was corrupted or misnamed (.woff renamed to .ttf); downloading a font at runtime and getting a 404 HTML body; embedding a variable/font collection format Sfnt2Woff does not support.

Related errors


AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31). Data as JSON: /api/errors/872f2f99187ceb08. Report an issue: GitHub.