denoland/deno · error · Error
Invalid digest: ${algorithm}
Error message
Invalid digest: ${algorithm} What it means
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').
Source
Thrown at ext/node/polyfills/internal/crypto/sig.ts:159
constructor(algorithm: string, _options?: any) {
validateString(algorithm, "algorithm");
ensureSignProtoSetup();
const W = getWritable();
FunctionPrototypeCall(W, this, {
write(chunk, enc, callback) {
this.update(chunk, enc);
callback();
},
});
algorithm = StringPrototypeToLowerCase(algorithm);
this.#digestType = algorithm;
try {
this.hash = createHash(this.#digestType);
} catch {
throw new Error(`Invalid digest: ${algorithm}`);
}
}
sign(
privateKey: any,
encoding?: any,
): Buffer | string {
if (!privateKey) {
throw new ERR_CRYPTO_SIGN_KEY_REQUIRED();
}
const res = prepareAsymmetricKey(privateKey, kConsumePrivate);
// Options specific to RSA
const rsaPadding = getPadding(privateKey);
// Options specific to RSA-PSS
const pssSaltLength = getSaltLength(privateKey);View on GitHub (pinned to 9ad36f7a2c)
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.
Example fix
// before
const s = new crypto.Sign('SHA-256');
// after
const s = new crypto.Sign('sha256');
// or guard: if (!crypto.getHashes().includes(algo.toLowerCase())) throw new Error('bad algo'); Defensive patterns
Strategy: validation
Validate before calling
const algo = String(rawAlgo).toLowerCase().replace(/-/g, ''); // 'SHA-256' -> 'sha256'
if (!crypto.getHashes().includes(algo)) throw new Error(`unsupported digest: ${rawAlgo}`);
const signer = new crypto.Sign(algo); Type guard
const isSupportedDigest = (a) => crypto.getHashes().includes(String(a).toLowerCase().replace(/-/g, ''));
Try / catch
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; } Prevention
- Translate WebCrypto names: 'SHA-256' → 'sha256' before use.
- Validate configurable algorithm names against crypto.getHashes() at startup.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ERR_INVALID_ARG_TYPE
- ERR_CRYPTO_HASH_FINALIZED
- ERR_OSSL_EVP_NOT_XOF_OR_INVALID_LENGTH
- ERR_INVALID_ARG_TYPE
- ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/5ea4b78096fb359b.
Report an issue: GitHub.