{"record":{"id":"5ea4b78096fb359b","repo":"denoland/deno","slug":"invalid-digest-algorithm","errorCode":null,"errorMessage":"Invalid digest: ${algorithm}","messagePattern":"Invalid digest: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/sig.ts","lineNumber":159,"sourceCode":"  constructor(algorithm: string, _options?: any) {\n    validateString(algorithm, \"algorithm\");\n\n    ensureSignProtoSetup();\n    const W = getWritable();\n    FunctionPrototypeCall(W, this, {\n      write(chunk, enc, callback) {\n        this.update(chunk, enc);\n        callback();\n      },\n    });\n\n    algorithm = StringPrototypeToLowerCase(algorithm);\n\n    this.#digestType = algorithm;\n    try {\n      this.hash = createHash(this.#digestType);\n    } catch {\n      throw new Error(`Invalid digest: ${algorithm}`);\n    }\n  }\n\n  sign(\n    privateKey: any,\n    encoding?: any,\n  ): Buffer | string {\n    if (!privateKey) {\n      throw new ERR_CRYPTO_SIGN_KEY_REQUIRED();\n    }\n\n    const res = prepareAsymmetricKey(privateKey, kConsumePrivate);\n\n    // Options specific to RSA\n    const rsaPadding = getPadding(privateKey);\n\n    // Options specific to RSA-PSS\n    const pssSaltLength = getSaltLength(privateKey);","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/sig.ts#L141-L177","documentation":"Thrown by the Sign class constructor in Deno's node:crypto polyfill (ext/node/polyfills/internal/crypto/sig.ts:159) when createHash(algorithm) fails, i.e. the digest name passed to new crypto.Sign(algorithm) is not a supported hash. The polyfill throws a plain Error ('Invalid digest: <name>') matching Node's message; in Node itself this carries code ERR_CRYPTO_INVALID_DIGEST. Note the name is lowercased before hashing, so case is not the issue — the algorithm itself must exist (e.g. 'sha1', 'sha256', 'sha512', 'blake2b512').","triggerScenarios":"new crypto.Sign('sha-256') (hyphenated WebCrypto-style name — use 'sha256'), 'SHA512' works but 'sha-3', 'md6', or a typo like 'sha2256' do not. Also passing null (allowed in Node for Ed25519) is not accepted by this string-validated constructor path.","commonSituations":"Reusing algorithm identifiers from WebCrypto/SubtleCrypto ('SHA-256') in node:crypto sign/verify flows; env-configurable algorithm names with a typo; assuming an exotic digest is available because OpenSSL lists it.","solutions":["Use node:crypto digest names: 'sha256' not 'sha-256' (see crypto.getHashes() output).","Validate user-supplied algorithm names against crypto.getHashes() before constructing Sign/Verify.","For Ed25519/Ed448 where Node allows a null digest, pass the digest used for the standard flow — with this polyfill supply a valid hash name or restructure to key-object signing per Node docs."],"exampleFix":"// before\nconst s = new crypto.Sign('SHA-256');\n\n// after\nconst s = new crypto.Sign('sha256');\n// or guard: if (!crypto.getHashes().includes(algo.toLowerCase())) throw new Error('bad algo');","handlingStrategy":"validation","validationCode":"const algo = String(rawAlgo).toLowerCase().replace(/-/g, ''); // 'SHA-256' -> 'sha256'\nif (!crypto.getHashes().includes(algo)) throw new Error(`unsupported digest: ${rawAlgo}`);\nconst signer = new crypto.Sign(algo);","typeGuard":"const isSupportedDigest = (a) => crypto.getHashes().includes(String(a).toLowerCase().replace(/-/g, ''));","tryCatchPattern":"try { signer = new crypto.Sign(algo); } catch (e) { if (/^Invalid digest:/.test(e.message)) { signer = new crypto.Sign('sha256'); /* or reject input */ } else throw e; }","preventionTips":["Translate WebCrypto names: 'SHA-256' → 'sha256' before use.","Validate configurable algorithm names against crypto.getHashes() at startup."],"tags":["node-compat","crypto","signing","hash","digest","unsupported-algorithm"],"backgroundTag":"unsupported-digest-algorithm","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}