{"record":{"id":"68203305ab03ad9a","repo":"denoland/deno","slug":"err-crypto-invalid-digest-682033","errorCode":"ERR_CRYPTO_INVALID_DIGEST","errorMessage":"Invalid digest: ${hashAlgorithm}","messagePattern":"Invalid digest: (.+?)","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/keygen.ts","lineNumber":442,"sourceCode":"          );\n        }\n      }\n\n      const {\n        hash,\n        mgf1Hash,\n        hashAlgorithm,\n        mgf1HashAlgorithm,\n        saltLength,\n      } = options;\n\n      if (saltLength !== undefined) {\n        validateInt32(saltLength, \"options.saltLength\", 0);\n      }\n      if (hashAlgorithm !== undefined) {\n        validateString(hashAlgorithm, \"options.hashAlgorithm\");\n        if (!getHashes().includes(hashAlgorithm)) {\n          throw new ERR_CRYPTO_INVALID_DIGEST(hashAlgorithm);\n        }\n      }\n      if (mgf1HashAlgorithm !== undefined) {\n        validateString(mgf1HashAlgorithm, \"options.mgf1HashAlgorithm\");\n        if (!getHashes().includes(mgf1HashAlgorithm)) {\n          throw new ERR_CRYPTO_INVALID_DIGEST(mgf1HashAlgorithm, \"MGF1\");\n        }\n      }\n      if (hash !== undefined) {\n        process.emitWarning(\n          '\"options.hash\" is deprecated, ' +\n            'use \"options.hashAlgorithm\" instead.',\n          \"DeprecationWarning\",\n          \"DEP0154\",\n        );\n        validateString(hash, \"options.hash\");\n        if (hashAlgorithm && hash !== hashAlgorithm) {\n          throw new ERR_INVALID_ARG_VALUE(\"options.hash\", hash);","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/keygen.ts#L424-L460","documentation":"When generating an 'rsa-pss' key pair, the PSS parameters are validated: if options.hashAlgorithm is provided it must be a string present in crypto.getHashes(), otherwise createJob throws ERR_CRYPTO_INVALID_DIGEST (ext/node/polyfills/internal/crypto/keygen.ts:439-444). The same rule applies one branch later to mgf1HashAlgorithm (with an 'MGF1' suffix on the error). These digests become the signing-digest constraints baked into the PSS key, so they must be real hash algorithms.","triggerScenarios":"generateKeyPairSync('rsa-pss', { modulusLength: 2048, hashAlgorithm: 'sha100' }); hashAlgorithm: 'SHA256' or 'sha-256' spellings not matching getHashes() entries; mgf1HashAlgorithm set to a digest the runtime does not expose (throws the sibling error); values taken from a JWT 'alg' string.","commonSituations":"Algorithm names from JOSE/JWT config ('PS256' does not name a hash; you need 'sha256'); mixed-casing from config files; switching runtimes where the exposed hash list differs; migrating RSA-PSS settings between OpenSSL CLI flags and node:crypto options.","solutions":["Use canonical lowercase names: hashAlgorithm: 'sha256' (or sha384/sha512).","Validate both hashAlgorithm and mgf1HashAlgorithm against crypto.getHashes() before generating.","Derive the hash name from the JOSE alg with an explicit mapping: PS256 -> 'sha256', PS384 -> 'sha384', PS512 -> 'sha512'."],"exampleFix":"// before\ncrypto.generateKeyPairSync('rsa-pss', {\n  modulusLength: 2048,\n  hashAlgorithm: 'SHA256', // not found in getHashes()\n});\n\n// after\ncrypto.generateKeyPairSync('rsa-pss', {\n  modulusLength: 2048,\n  hashAlgorithm: 'sha256',\n  mgf1HashAlgorithm: 'sha256',\n});","handlingStrategy":"validation","validationCode":"const PSS_HASH = { PS256: 'sha256', PS384: 'sha384', PS512: 'sha512' };\nconst hash = PSS_HASH[joseAlg] ?? cfg.hashAlgorithm?.toLowerCase();\nif (hash != null && !crypto.getHashes().includes(hash)) {\n  throw new Error(`rsa-pss hash '${hash}' not available; use sha256/sha384/sha512`);\n}\ncrypto.generateKeyPairSync('rsa-pss', { modulusLength: 2048, hashAlgorithm: hash });","typeGuard":"function isPssHash(name) {\n  return ['sha256', 'sha384', 'sha512'].includes(String(name).toLowerCase());\n}","tryCatchPattern":"try {\n  crypto.generateKeyPairSync('rsa-pss', { modulusLength, hashAlgorithm: cfg.hash });\n} catch (e) {\n  if (e.code === 'ERR_CRYPTO_INVALID_DIGEST') {\n    return crypto.generateKeyPairSync('rsa-pss', { modulusLength, hashAlgorithm: 'sha256' });\n  }\n  throw e;\n}","preventionTips":["Map JOSE PS* algorithms to lowercase OpenSSL hash names explicitly.","Validate hashAlgorithm and mgf1HashAlgorithm against crypto.getHashes().","Keep PSS hash config lowercase and pinned in config, not free-form input."],"tags":["crypto","key-generation","rsa-pss","digest-algorithm","node-compat"],"backgroundTag":"unsupported-hash-algorithm","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}