{"record":{"id":"dc5a8b748b0bb579","repo":"denoland/deno","slug":"no-default-digest","errorCode":null,"errorMessage":"no default digest","messagePattern":"no default digest","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/sig.ts","lineNumber":574,"sourceCode":"      }\n      result = op_node_verify_ed448(handle, dataBytes, signature);\n    } else if (\n      keyType === \"x25519\" || keyType === \"x448\" || keyType === \"dh\"\n    ) {\n      throw new TypeError(\n        \"operation not supported for this keytype\",\n      );\n    } else {\n      let digest = algorithm;\n      if (digest == null) {\n        if (keyType === \"rsa-pss\") {\n          const details = op_node_get_asymmetric_key_details(handle);\n          if (details.hashAlgorithm) {\n            digest = details.hashAlgorithm;\n          }\n        }\n        if (digest == null) {\n          throw new TypeError(\"no default digest\");\n        }\n      }\n      // Preserve padding/saltLength options from the original key\n      const publicKeyObject = new PublicKeyObject(handle);\n      const verifyKey = typeof key === \"object\" &&\n          !(ObjectPrototypeIsPrototypeOf(KeyObject.prototype, key))\n        ? { ...key, key: publicKeyObject }\n        : publicKeyObject;\n      result = Verify(digest).update(dataBytes)\n        .verify(verifyKey, signature);\n    }\n\n    if (callback) {\n      setTimeout(() => callback(null, result));\n    } else {\n      return result;\n    }\n  } catch (err) {","sourceCodeStart":556,"sourceCodeEnd":592,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/sig.ts#L556-L592","documentation":"The verify-side counterpart of the sign constraint, with a different message: for non-ed25519/ed448 keys, one-shot crypto.verify() defaults the digest only when an rsa-pss key carries an embedded hashAlgorithm; for rsa, ecdsa, dsa, or bare rsa-pss keys an explicit algorithm is required, otherwise TypeError(\"no default digest\").","triggerScenarios":"crypto.verify(null, data, rsaPubKey, sig); crypto.verify(null, data, ecPubKey, sig); ed25519-first verify helpers that always pass null.","commonSituations":"Code written against ed25519 (where null is correct) reused with RSA/EC keys; porting from WebCrypto where the hash travels with the key; rs256 JWT verification refactored to a digestless call.","solutions":["Pass an explicit digest: crypto.verify(\"sha256\", data, pubKey, sig).","Branch on key.asymmetricKeyType — null only for ed25519/ed448 (and rsa-pss with embedded hash).","Derive the digest from the JOSE alg header for JWT verification (RS256 -> \"sha256\")."],"exampleFix":"// before\nconst ok = crypto.verify(null, data, pubKey, sig); // throws: no default digest\n\n// after\nconst alg = pubKey.asymmetricKeyType === \"ed25519\" || pubKey.asymmetricKeyType === \"ed448\" ? null : \"sha256\";\nconst ok = crypto.verify(alg, data, pubKey, sig);","handlingStrategy":"validation","validationCode":"function requiredVerifyDigest(key, requested) {\n  if (requested != null) return requested;\n  const t = key.asymmetricKeyType ?? key.key?.asymmetricKeyType;\n  if (t === \"ed25519\" || t === \"ed448\") return null;\n  throw new Error(`an explicit digest (e.g. \"sha256\") is required to verify with ${t} keys`);\n}\nconst ok = crypto.verify(requiredVerifyDigest(pubKey, alg), data, pubKey, sig);","typeGuard":"const needsExplicitVerifyDigest = (key) => {\n  const t = key.asymmetricKeyType ?? key.key?.asymmetricKeyType;\n  return t !== \"ed25519\" && t !== \"ed448\" && t !== \"rsa-pss\";\n};","tryCatchPattern":"try {\n  ok = crypto.verify(digest, data, pubKey, sig);\n} catch (e) {\n  if (e instanceof TypeError && /no default digest/.test(e.message)) {\n    throw new Error(`pass an explicit digest for key type ${pubKey.asymmetricKeyType}`);\n  }\n  throw e;\n}","preventionTips":["null is only valid for ed25519/ed448 (and rsa-pss with an embedded hashAlgorithm).","For JWTs, derive the digest from the alg header: RS256 -> sha256, ES512 -> sha512, EdDSA -> null.","Use the same digest for sign and verify — a mismatch often shows up as this or a false-negative verify."],"tags":["crypto","verification","digest","algorithm-required"],"backgroundTag":"missing-digest-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"}