{"record":{"id":"09a617dab58a70e4","repo":"mozilla/pdf.js","slug":"unsupported-encryption-algorithm","errorCode":null,"errorMessage":"unsupported encryption algorithm","messagePattern":"unsupported encryption algorithm","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/crypto.js","lineNumber":1074,"sourceCode":"    }\n    const hash = calculateMD5(key, 0, i);\n    return hash.subarray(0, Math.min(n + 5, 16));\n  }\n\n  constructor(dict, fileId, password) {\n    const filter = dict.get(\"Filter\");\n    if (!isName(filter, \"Standard\")) {\n      throw new FormatError(\"unknown encryption method\");\n    }\n    this.filterName = filter.name;\n    this.dict = dict;\n    this.#fileId = fileId;\n    const algorithm = dict.get(\"V\");\n    if (\n      !Number.isInteger(algorithm) ||\n      (algorithm !== 1 && algorithm !== 2 && algorithm !== 4 && algorithm !== 5)\n    ) {\n      throw new FormatError(\"unsupported encryption algorithm\");\n    }\n    this.algorithm = algorithm;\n    let keyLength = dict.get(\"Length\");\n    if (!keyLength) {\n      // Spec asks to rely on encryption dictionary's Length entry, however\n      // some PDFs don't have it. Trying to recover.\n      if (algorithm <= 3) {\n        // For 1 and 2 it's fixed to 40-bit, for 3 40-bit is a minimal value.\n        keyLength = 40;\n      } else {\n        // Trying to find default handler -- it usually has Length.\n        const cfDict = dict.get(\"CF\");\n        const streamCryptoName = dict.get(\"StmF\");\n        if (cfDict instanceof Dict && streamCryptoName instanceof Name) {\n          cfDict.suppressEncryption = true; // See comment below.\n          const handlerDict = cfDict.get(streamCryptoName.name);\n          keyLength = handlerDict?.get(\"Length\") || 128;\n          if (keyLength < 40) {","sourceCodeStart":1056,"sourceCodeEnd":1092,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/crypto.js#L1056-L1092","documentation":"Thrown when the encryption dictionary's V entry is missing, not an integer, or not one of the supported algorithm codes 1, 2, 4, or 5. V selects the encryption algorithm version; V=3 (a deprecated variable-length RC4 variant) and any newer/unknown V value are not implemented. The PDF cannot be decrypted.","triggerScenarios":"Loading a PDF with V=3 (rare legacy producers); a PDF whose /Encrypt dict has a missing or non-integer V entry due to corruption; a PDF using a hypothetical future algorithm code pdf.js has not adopted.","commonSituations":"Corrupt/truncated Encrypt dict from a bad download or buggy producer; very old PDFs that used V=3 RC4 variants; hand-edited PDFs where V was altered.","solutions":["Re-encrypt the PDF with a supported algorithm (V=2 RC4-40/128, V=4 AES-128/RC4, or V=5 AES-256) via qpdf or Acrobat.","If V is corrupt, repair the xref/Encrypt dict with qpdf --check or by re-saving through Acrobat.","Surface an 'unsupported encryption algorithm' user message rather than propagating the FormatError."],"exampleFix":"// before\nconst doc = await getDocument({ url, password }).promise;\n\n// after — map to a user-facing message\ntry {\n  const doc = await getDocument({ url, password }).promise;\n} catch (e) {\n  if (e.message === 'unsupported encryption algorithm') {\n    throw new Error('Unsupported encryption algorithm (V=' + (e.detail ?? 'unknown') + '). Only V=1,2,4,5 are supported.');\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const doc = await getDocument({ url }).promise;\n} catch (e) {\n  if (e.name === 'FormatError' && e.message === 'unsupported encryption algorithm') {\n    notifyUser('Unsupported encryption algorithm; only V=1,2,4,5 are supported.');\n    return;\n  }\n  throw e;\n}","preventionTips":["Re-encrypt PDFs through qpdf --encrypt to V=2, 4, or 5 before ingestion.","When generating PDFs, pin a supported algorithm version.","Surface a clear message rather than letting FormatError bubble to the UI."],"tags":["encryption","pdf-security","format-error","unsupported-feature"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}