mozilla/pdf.js · error · FormatError
Unicode ranges Bits > 123 are reserved for internal usage
Error message
Unicode ranges Bits > 123 are reserved for internal usage
What it means
Thrown while building the OS/2 ulUnicodeRange bitmask fields when getUnicodeRangeFor() returns a position >= 123. The OS/2 table has four 32-bit ulUnicodeRange fields (128 bits total), but only positions 0–122 are defined by the OpenType spec; positions 123–127 are reserved for internal usage and pdf.js refuses to set them.
Source
Thrown at src/core/fonts.js:838
code |= 0;
if (firstCharIndex > code || !firstCharIndex) {
firstCharIndex = code;
}
if (lastCharIndex < code) {
lastCharIndex = code;
}
position = getUnicodeRangeFor(code, position);
if (position < 32) {
ulUnicodeRange1 |= 1 << position;
} else if (position < 64) {
ulUnicodeRange2 |= 1 << (position - 32);
} else if (position < 96) {
ulUnicodeRange3 |= 1 << (position - 64);
} else if (position < 123) {
ulUnicodeRange4 |= 1 << (position - 96);
} else {
throw new FormatError(
"Unicode ranges Bits > 123 are reserved for internal usage"
);
}
}
if (lastCharIndex > 0xffff) {
// OS2 only supports a 16 bit int. The spec says if supplementary
// characters are used the field should just be set to 0xFFFF.
lastCharIndex = 0xffff;
}
} else {
// TODO
firstCharIndex = 0;
lastCharIndex = 255;
}
const bbox = properties.bbox || [0, 0, 0, 0];
const unitsPerEm =
override.unitsPerEm ||View on GitHub (pinned to 5903d58d58)
Solutions
- Inspect the font's charstrings/cmap with fonttools to identify glyphs mapped to unusual Unicode values and remove or remap them.
- Rebuild the OS/2 table with fonttools after cleaning the cmap: font['OS/2'] = rebuilt; font.save('fixed.ttf').
- If you control the font generation pipeline, filter out code points that map to undefined OS/2 Unicode ranges (positions >= 123).
- Replace the problematic embedded font with a standard one.
Example fix
# before — font has private-use glyphs in undefined ranges
from fontTools import ttLib
font = ttLib.TTFont('broken.ttf')
# after — filter cmap entries to defined Unicode ranges before embedding
cmap = font.getBestCmap()
for cp in list(cmap.keys()):
if cp > 0x2FFFF: # drop problematic supplementary/private-use
del cmap[cp]
font.save('fixed.ttf') Defensive patterns
Strategy: validation
Validate before calling
// Server-side: check Unicode code points against OS/2 range limits
// before embedding the font.
// from fontTools import ttLib
// font = ttLib.TTFont('font.ttf')
// cmap = font.getBestCmap()
// for cp in cmap:
// if cp > 0xE01EF and cp < 0xF0000: # supplementary private use etc.
// print(f'Warning: code point U+{cp:04X} may exceed OS/2 range 123')
function checkUnicodeRanges(font) {
const cmap = font.tables.cmap;
// Inspect code points; anything in very high planes may trigger this
const risky = cmap.codePoints.filter(cp => cp > 0x3FFFF);
return risky.length === 0;
} Try / catch
try {
await page.render(renderParams).promise;
} catch (err) {
if (err.message?.includes('Unicode ranges Bits > 123')) {
console.warn('Font has code points beyond defined OS/2 Unicode ranges; font load failed.');
} else { throw err; }
} Prevention
- Filter out private-use and unassigned Unicode code points from font cmaps before embedding.
- Rebuild the OS/2 table with fonttools after cleaning the cmap.
- Use ots-sanitize to validate OS/2 table integrity.
When it happens
Trigger: In createOS2Table(), iterating over charstrings entries, getUnicodeRangeFor(code, position) returns a value >= 123 for some character code. This means the font contains glyphs mapped to Unicode code points that fall into undefined OS/2 range groups.
Common situations: Fonts with very unusual or very-high Unicode code points (supplementary private-use areas, unassigned planes). Corrupt charstrings maps that include bogus code values. Custom or experimental fonts with private-use area characters beyond the defined ranges. Fonts processed by tools that generate invalid Unicode mappings.
Related errors
- unsupported cmap: ${format}
- Required "maxp" table is not found
- "maxp" table has a wrong version number
- Required "head" table is not found
- Required "hhea" table is not found
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/13c2c5e69d37eb16.
Report an issue: GitHub.