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

  1. Inspect the font's charstrings/cmap with fonttools to identify glyphs mapped to unusual Unicode values and remove or remap them.
  2. Rebuild the OS/2 table with fonttools after cleaning the cmap: font['OS/2'] = rebuilt; font.save('fixed.ttf').
  3. If you control the font generation pipeline, filter out code points that map to undefined OS/2 Unicode ranges (positions >= 123).
  4. 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

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


AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13). Data as JSON: /api/errors/13c2c5e69d37eb16. Report an issue: GitHub.