{"record":{"id":"ec64812f7d44743a","repo":"denoland/deno","slug":"err-crypto-invalid-digest-ec6481","errorCode":"ERR_CRYPTO_INVALID_DIGEST","errorMessage":"Invalid digest: ${algorithm}","messagePattern":"Invalid digest: (.+?)","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/util.ts","lineNumber":346,"sourceCode":"  dss1: 64,\n  sha224: 64,\n  sha256: 64,\n  sha384: 128,\n  sha512: 128,\n  \"sha512-224\": 128,\n  \"sha512-256\": 128,\n  \"sha3-224\": 144,\n  \"sha3-256\": 136,\n  \"sha3-384\": 104,\n  \"sha3-512\": 72,\n  blake2b512: 128,\n  blake2s256: 64,\n};\n\nfunction getHashBlockSize(algorithm: string): number {\n  const blockSize = hashBlockSizes[algorithm];\n  if (blockSize === undefined) {\n    throw new ERR_CRYPTO_INVALID_DIGEST(algorithm);\n  }\n  return blockSize;\n}\n\nfunction getCipherInfo(\n  nameOrNid: string | number,\n  options?: { keyLength?: number; ivLength?: number },\n) {\n  if (typeof nameOrNid !== \"string\" && typeof nameOrNid !== \"number\") {\n    throw new ERR_INVALID_ARG_TYPE(\n      \"nameOrNid\",\n      [\"string\", \"number\"],\n      nameOrNid,\n    );\n  }\n\n  if (typeof nameOrNid === \"number\") {\n    validateInt32(nameOrNid, \"nameOrNid\");","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/util.ts#L328-L364","documentation":"getHashBlockSize() backs the Hmac constructor (crypto.createHmac(digest, key)): it looks the digest up in a fixed block-size table (sha*, sha3*, blake2*, md5, ...) used to pad/HMAC keys. A digest missing from the table throws ERR_CRYPTO_INVALID_DIGEST. Note this is a coded error, unlike the plain \"Invalid digest\" Error from the Sign/Verify constructors.","triggerScenarios":"crypto.createHmac(\"sha-256\", key) (hyphenated name); createHmac(\"md4\", key); createHmac(\"sm3\"/\"ripemd160\", key) — any name whose lowercase form has no block-size entry. The digest is lowercased first, so \"SHA256\" works but \"SHA-256\" does not.","commonSituations":"Algorithm strings copied from JOSE/JWS headers (\"SHA-256\") or OpenSSL docs; typo'd digest names; switching from createHash() (which supports a wider alias set) to createHmac().","solutions":["Use canonical names: \"md5\", \"sha1\", \"sha256\", \"sha384\", \"sha512\", \"sha3-*\", \"blake2b512\", \"blake2s256\".","Validate first: crypto.getHashes().includes(digest.toLowerCase()).","Normalize config values by stripping hyphens and lowercasing before use."],"exampleFix":"// before\nconst h = crypto.createHmac(\"SHA-256\", secret); // lowercases to \"sha-256\" -> ERR_CRYPTO_INVALID_DIGEST\n\n// after\nconst h = crypto.createHmac(\"sha256\", secret);","handlingStrategy":"validation","validationCode":"const digest = configuredHmacAlg.toLowerCase().replace(/-/g, \"\");\nif (!crypto.getHashes().includes(digest)) {\n  throw new Error(`HMAC digest \"${configuredHmacAlg}\" unsupported; see crypto.getHashes()`);\n}\nconst h = crypto.createHmac(digest, secret);","typeGuard":"const isHmacDigest = (name) =>\n  typeof name === \"string\" && crypto.getHashes().includes(name.toLowerCase().replace(/-/g, \"\"));","tryCatchPattern":"try {\n  hmac = crypto.createHmac(digest, secret);\n} catch (e) {\n  if (e?.code === \"ERR_CRYPTO_INVALID_DIGEST\") {\n    throw new Error(`digest \"${digest}\" has no block size (unsupported for HMAC)`);\n  }\n  throw e;\n}","preventionTips":["Normalize digest names (lowercase, strip hyphens) before any crypto call.","Restrict config to a whitelist of canonical names: sha256, sha384, sha512.","This one is coded (ERR_CRYPTO_INVALID_DIGEST) unlike the Sign/Verify constructors' plain Error."],"tags":["crypto","hmac","digest","typo"],"backgroundTag":"unsupported-hash-algorithm","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}