d2lang/d2 · error
invalid font collection
Error message
invalid font collection
What it means
For TrueType collections (ttcf), bytes 8–12 hold the offset of the first font in the collection; it must be non-zero and the file must be at least 16 bytes. A zero offset or too-short collection header is rejected.
Source
Thrown at lib/textmeasure/fontface.go:197
for i := range pairs {
offset := 18 + 6*i
pairs[i] = kernPair{
key: binary.BigEndian.Uint32(table[offset : offset+4]),
value: int16(binary.BigEndian.Uint16(table[offset+4 : offset+6])),
}
}
return pairs, nil
}
func sfntTable(src []byte, tag string) ([]byte, error) {
if len(src) < 12 {
return nil, fmt.Errorf("invalid sfnt: too short")
}
base := 0
if string(src[:4]) == "ttcf" {
if len(src) < 16 || binary.BigEndian.Uint32(src[8:12]) == 0 {
return nil, fmt.Errorf("invalid font collection")
}
base = int(binary.BigEndian.Uint32(src[12:16]))
if base < 0 || base+12 > len(src) {
return nil, fmt.Errorf("invalid font collection offset")
}
}
n := int(binary.BigEndian.Uint16(src[base+4 : base+6]))
records := base + 12
if n > (len(src)-records)/16 {
return nil, fmt.Errorf("invalid sfnt table directory")
}
for i := 0; i < n; i++ {
record := src[records+16*i : records+16*(i+1)]
if string(record[:4]) != tag {
continue
}
offset := int(binary.BigEndian.Uint32(record[8:12]))View on GitHub (pinned to 0d69dca6f5)
Solutions
- Re-acquire the .ttc file from a trusted source.
- Split the collection into single .ttf fonts (e.g. with fonttools: fonttools ttLib.ttCollection) and use individual fonts.
- Validate the ttcf header (magic, version, non-zero offsets) before passing the data to the library.
Defensive patterns
Strategy: validation
Validate before calling
func validTTC(data []byte) bool {
if len(data) < 16 || string(data[:4]) != "ttcf" { return len(data) >= 12 }
return binary.BigEndian.Uint32(data[8:12]) != 0
} Try / catch
if err := loadAndParseFont(path); err != nil {
log.Printf("font collection unusable (%v); falling back to single font", err)
return loadSingleFont(fallbackPath)
} Prevention
- Prefer single .ttf files over .ttc collections unless you control the collection build
- Validate ttcf headers (magic, version, non-zero offsets) before loading
- Regenerate .ttc files with fonttools ttCollection instead of merging binaries manually
- Verify checksums of font collections after transfer
When it happens
Trigger: parseFont is given a .ttc font collection whose header declares version 'ttcf' but has a zero first-font offset or a truncated (<16 byte) header.
Common situations: Corrupted or hand-merged .ttc files; fonts harvested from system font caches in partial form.
Related errors
- invalid font collection offset
- invalid kern table length
- invalid sfnt table directory
- checksum error in table: %v
- invalid kern table: too short
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/0c31d9c6bde6e555.
Report an issue: GitHub.