{"record":{"id":"07ee0f258854c867","repo":"mozilla/pdf.js","slug":"bad-compressed-xref-entry-ref","errorCode":null,"errorMessage":"Bad (compressed) XRef entry: ${ref}","messagePattern":"Bad \\(compressed\\) XRef entry: (.+?)","errorType":"exception","errorClass":"XRefEntryException","httpStatus":null,"severity":"error","filePath":"src/core/xref.js","lineNumber":1037,"sourceCode":"      entries[i] = obj;\n      if (obj instanceof BaseStream) {\n        continue;\n      }\n      const num = nums[i],\n        entry = this.#entries[num];\n      if (entry && entry.offset === tableOffset && entry.gen === i) {\n        if (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"TESTING\")) {\n          assert(\n            obj !== undefined,\n            'fetchCompressed: The \"obj\" cannot be undefined.'\n          );\n        }\n        this.#cacheMap.set(num, obj);\n      }\n    }\n    xrefEntry = entries[xrefEntry.gen];\n    if (xrefEntry === undefined) {\n      throw new XRefEntryException(`Bad (compressed) XRef entry: ${ref}`);\n    }\n    return xrefEntry;\n  }\n\n  async fetchIfRefAsync(obj, suppressEncryption) {\n    return obj instanceof Ref ? this.fetchAsync(obj, suppressEncryption) : obj;\n  }\n\n  async fetchAsync(ref, suppressEncryption) {\n    try {\n      return this.fetch(ref, suppressEncryption);\n    } catch (ex) {\n      if (!(ex instanceof MissingDataException)) {\n        throw ex;\n      }\n      await this.pdfManager.requestRange(ex.begin, ex.end);\n      return this.fetchAsync(ref, suppressEncryption);\n    }","sourceCodeStart":1019,"sourceCodeEnd":1055,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/xref.js#L1019-L1055","documentation":"An XRefEntryException thrown at the end of XRef.fetchCompressed: after building the entries array of length N, the lookup entries[xrefEntry.gen] is undefined. The compressed xref entry's generation field is meant to be the index into the ObjStm's object list; if gen is out of range (>= N) the requested object does not exist in that stream. The full Ref is included in the message.","triggerScenarios":"A compressed xref entry whose generation index points past the end of the ObjStm object list; /N undercount relative to the entry's index; a corrupted generation value; a stream that was rewritten with fewer objects than the xref expects.","commonSituations":"Inconsistent xref vs object stream after a botched incremental update; buggy writers; files edited by hand or by non-conformant tools.","solutions":["Repair with qpdf --check / mutool clean to rebuild the cross-reference.","Re-export the PDF.","Catch XRefEntryException at the page-access boundary and skip the affected object/page."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const page = await doc.getPage(n);\n} catch (e) {\n  // XRefEntryException is not always exported; match by name.\n  if (e.name === 'XRefEntryException' || /Bad \\(compressed\\) XRef entry/.test(e.message)) {\n    console.warn(`Page ${n} unavailable: bad compressed xref entry`);\n    continue;\n  }\n  throw e;\n}","preventionTips":["Rebuild the cross-reference with qpdf/mutool before loading.","Catch and skip at the page boundary.","Validate incremental-update consistency in your PDF generator."],"tags":["xref","objstm","corruption","xref-entry-exception"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}