mozilla/pdf.js · error · FormatError
Required "head" table is not found
Error message
Required "head" table is not found
What it means
Thrown when the font's table directory lacks a 'head' table. The head table is mandatory — it carries the font's unitsPerEm, bbox, indexToLocFormat, and other critical metadata. Note that sanitizeMetrics is called with tables.head before this check (it tolerates a null head), but sanitizeHead() requires the table and the subsequent code reads head.data directly.
Source
Thrown at src/core/fonts.js:2961
if (!hintsValid) {
delete tables.fpgm;
delete tables.prep;
delete tables["cvt "];
}
// Ensure the hmtx table contains the advance width and
// sidebearings information for numGlyphs in the maxp table
sanitizeMetrics(
font,
tables.hhea,
tables.hmtx,
tables.head,
numGlyphsOut,
dupFirstEntry
);
if (!tables.head) {
throw new FormatError('Required "head" table is not found');
}
sanitizeHead(tables.head, numGlyphs, isTrueType ? tables.loca.length : 0);
let missingGlyphs = Object.create(null);
if (isTrueType) {
const glyphsInfo = sanitizeGlyphLocations(
tables.loca,
tables.glyf,
numGlyphs,
isGlyphLocationsLong,
hintsValid,
dupFirstEntry,
maxSizeOfInstructions
);
missingGlyphs = glyphsInfo.missingGlyphs;
// Some fonts have incorrect maxSizeOfInstructions values, so we useView on GitHub (pinned to 5903d58d58)
Solutions
- Replace the font with a complete, valid copy that includes a head table.
- Rebuild the font with fonttools (load + save) to regenerate the head table.
- Validate the embedded font stream with ots-sanitize before deployment.
- If generating PDFs, ensure font embedding includes all mandatory tables.
Example fix
# rebuild head table via fonttools round-trip
from fontTools import ttLib
font = ttLib.TTFont('broken.ttf')
# accessing font['head'] forces fontTools to parse/rebuild
_ = font['head'].unitsPerEm
font.save('fixed.ttf') Defensive patterns
Strategy: validation
Validate before calling
// Server-side: verify font has head table
// from fontTools import ttLib
// font = ttLib.TTFont('font.ttf')
// assert 'head' in font, 'Font missing head table'
Try / catch
try {
await page.render(renderParams).promise;
} catch (err) {
if (err.message?.includes('Required "head" table is not found')) {
console.error('Font missing head table; replace embedded font.');
} else { throw err; }
} Prevention
- Ensure all fonts include the mandatory head table before embedding.
- Rebuild fonts with fonttools to regenerate missing core tables.
- Validate fonts with ots-sanitize — it flags missing head as critical.
When it happens
Trigger: After sanitizeMetrics completes, the check if (!tables.head) at line 2960 throws. This is reached for fonts that passed the earlier CFF divert check (had CFF + OTTO header + complete core tables) or TrueType fonts that passed the loca/glyf checks.
Common situations: A corrupt or severely stripped font missing the head table. A font file where the table directory is intact but the head table data was truncated. Non-standard fonts from unreliable sources. PDFs with damaged embedded font streams.
Related errors
- Required "maxp" table is not found
- Required "hhea" table is not found
- unsupported cmap: ${format}
- Unicode ranges Bits > 123 are reserved for internal usage
- Could not fix indexToLocFormat: ${indexToLocFormat}
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/3831feae538ee197.
Report an issue: GitHub.