denoland/deno · error · NodeTypeError
ERR_CRYPTO_INVALID_DIGEST
ERR_CRYPTO_INVALID_DIGEST
Error message
Invalid digest: ${digest} What it means
After pbkdf2 lowercases the digest string and forwards it to the native op, a digest the crypto backend does not recognize makes op_node_pbkdf2 return false and the JS layer throws ERR_CRYPTO_INVALID_DIGEST. digest must be a string naming a known digest algorithm (e.g., 'sha256', 'sha384', 'sha512', 'md5'); note the argument is validated as a string earlier, so this error is specifically about unknown names, not wrong types.
Source
Thrown at ext/node/polyfills/internal/crypto/pbkdf2.ts:95
password: any,
salt: any,
iterations: number,
keylen: number,
digest: string,
): Buffer {
({ password, salt, iterations, keylen, digest } = check(
password,
salt,
iterations,
keylen,
digest,
));
digest = StringPrototypeToLowerCase(digest);
const DK = new Uint8Array(keylen);
if (!op_node_pbkdf2(password, salt, iterations, digest, DK)) {
throw new ERR_CRYPTO_INVALID_DIGEST(digest);
}
return Buffer.from(DK);
}
/**
* @param iterations Needs to be higher or equal than zero
* @param keylen Needs to be higher or equal than zero but less than max allocation size (2^30)
* @param digest Algorithm to be used for encryption
*/
function pbkdf2(
password: any,
salt: any,
iterations: number,
keylen: number,
digest: string,
callback: (err: Error | null, derivedKey?: Buffer) => void,
) {View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Use a canonical lowercase name such as 'sha256', 'sha384' or 'sha512'
- Validate digest against crypto.getHashes() before calling pbkdf2
- Set an explicit default digest in your config layer instead of letting it fall through to undefined/''
Example fix
// before const dk = crypto.pbkdf2Sync(pw, salt, iterations, 32, cfg.hash); // cfg.hash = 'sha356' -> throws // after const digest = crypto.getHashes().includes(cfg.hash) ? cfg.hash : 'sha256'; const dk = crypto.pbkdf2Sync(pw, salt, iterations, 32, digest);
Defensive patterns
Strategy: validation
Validate before calling
if (typeof digest !== 'string' || !crypto.getHashes().includes(digest)) {
throw new Error(`unsupported pbkdf2 digest: ${String(digest)}`);
}
crypto.pbkdf2Sync(password, salt, iterations, keylen, digest); Type guard
function isSupportedDigest(name: string): boolean {
return crypto.getHashes().includes(name);
} Try / catch
try {
crypto.pbkdf2Sync(password, salt, iterations, keylen, digest);
} catch (e) {
if (e?.code === 'ERR_CRYPTO_INVALID_DIGEST') {
crypto.pbkdf2Sync(password, salt, iterations, keylen, 'sha256'); // explicit fallback
} else throw e;
} Prevention
- Pin the digest to a constant ('sha256'/'sha512') instead of accepting it from config
- Validate digest names against crypto.getHashes() at startup
- Guard optional config fields from defaulting to empty strings
When it happens
Trigger: crypto.pbkdf2Sync(pw, salt, 100000, 32, 'sha5123') — a misspelled, empty, or unsupported digest name reaches the native digest lookup and fails; same for the async crypto.pbkdf2 form.
Common situations: Digest names copied from another library's enum or a WebCrypto constant that does not map to a native name; typos in configuration ('sha356', 'sha-2'); an optional digest config field left as empty string and defaulted through.
Related errors
- ERR_INVALID_ARG_TYPE
- ERR_CRYPTO_HASH_FINALIZED
- ERR_OSSL_EVP_NOT_XOF_OR_INVALID_LENGTH
- ERR_INVALID_ARG_TYPE
- PBKDF2 keys are not extractable
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/e3d6a71ff8fc7d16.
Report an issue: GitHub.