{"record":{"id":"9ef46c50ce9c04d5","repo":"mozilla/pdf.js","slug":"invalid-cff-header","errorCode":null,"errorMessage":"Invalid CFF header","messagePattern":"Invalid CFF header","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/cff_parser.js","lineNumber":394,"sourceCode":"    cff.charStrings = charStringsAndSeacs.charStrings;\n    cff.seacs = charStringsAndSeacs.seacs;\n    cff.widths = charStringsAndSeacs.widths;\n\n    return cff;\n  }\n\n  parseHeader() {\n    let bytes = this.bytes;\n    const bytesLength = bytes.length;\n    let offset = 0;\n\n    // Prevent an infinite loop, by checking that the offset is within the\n    // bounds of the bytes array. Necessary in empty, or invalid, font files.\n    while (offset < bytesLength && bytes[offset] !== 1) {\n      ++offset;\n    }\n    if (offset >= bytesLength) {\n      throw new FormatError(\"Invalid CFF header\");\n    }\n    if (offset !== 0) {\n      info(\"cff data is shifted\");\n      bytes = bytes.subarray(offset);\n      this.bytes = bytes;\n    }\n    const major = bytes[0];\n    const minor = bytes[1];\n    const hdrSize = bytes[2];\n    const offSize = bytes[3];\n    const header = new CFFHeader(major, minor, hdrSize, offSize);\n    return { obj: header, endPos: hdrSize };\n  }\n\n  parseDict(dict) {\n    const view = new DataView(dict.buffer, dict.byteOffset, dict.bytesLength);\n    let pos = 0;\n","sourceCodeStart":376,"sourceCodeEnd":412,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/cff_parser.js#L376-L412","documentation":"Thrown by CFFParser.parseHeader while locating the CFF major-version byte (value 1). The parser scans the byte stream for a 1 and never finds one within bounds, meaning the data does not contain a valid CFF header. This indicates an empty, truncated, or non-CFF font stream.","triggerScenarios":"Parsing a font whose embedded CFF program has no byte equal to 1 (the required major version) — empty streams, random garbage, or a stream that is actually TrueType/glyf mislabeled as CFF. Triggered during font loading for any page using the affected font.","commonSituations":"Corrupt embedded fonts in downloaded PDFs; fonts damaged by partial file transfer; PDFs whose font streams were stripped to zero length by optimizing tools; CIDFont/CFF2 streams that fail the legacy major-version scan.","solutions":["Let pdf.js handle it: it catches the FormatError and substitutes a fallback system font, so usually no action is needed beyond accepting the substitution.","Re-save the PDF through Ghostscript (gs -sDEVICE=pdfwrite) to re-embed or repair the font.","If you control the source, re-embed the font correctly with a valid CFF program.","If rendering must not degrade, pre-validate fonts with a tool like fontTools before embedding."],"exampleFix":"// pdf.js recovers internally; callers just observe the render task promise.\nconst renderTask = page.render({ canvasContext, viewport });\ntry {\n  await renderTask.promise;\n} catch (e) {\n  // Font failed to parse and could not be substituted; render is incomplete.\n  console.warn('Render failed, possibly due to a corrupt embedded font:', e);\n}","handlingStrategy":"fallback","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  await page.render({ canvasContext, viewport }).promise;\n} catch (e) {\n  // CFF header invalid; pdf.js attempts system-font substitution.\n  // If substitution also failed, the page is only partially rendered.\n  console.warn('Font parse failure (invalid CFF header):', e);\n}","preventionTips":["Pre-validate embedded fonts with fontTools (ttx) before shipping PDFs.","Re-embed fonts through Ghostscript to repair corrupt CFF programs.","Keep pdf.js up to date; later versions add more font-repair fallbacks."],"tags":["font","cff","cff-parser","corrupt-font","font-substitution"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}