denoland/deno · error · TypeError

no default digest

Error message

no default digest

What it means

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").

Source

Thrown at ext/node/polyfills/internal/crypto/sig.ts:574

      }
      result = op_node_verify_ed448(handle, dataBytes, signature);
    } else if (
      keyType === "x25519" || keyType === "x448" || keyType === "dh"
    ) {
      throw new TypeError(
        "operation not supported for this keytype",
      );
    } else {
      let digest = algorithm;
      if (digest == null) {
        if (keyType === "rsa-pss") {
          const details = op_node_get_asymmetric_key_details(handle);
          if (details.hashAlgorithm) {
            digest = details.hashAlgorithm;
          }
        }
        if (digest == null) {
          throw new TypeError("no default digest");
        }
      }
      // Preserve padding/saltLength options from the original key
      const publicKeyObject = new PublicKeyObject(handle);
      const verifyKey = typeof key === "object" &&
          !(ObjectPrototypeIsPrototypeOf(KeyObject.prototype, key))
        ? { ...key, key: publicKeyObject }
        : publicKeyObject;
      result = Verify(digest).update(dataBytes)
        .verify(verifyKey, signature);
    }

    if (callback) {
      setTimeout(() => callback(null, result));
    } else {
      return result;
    }
  } catch (err) {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Pass an explicit digest: crypto.verify("sha256", data, pubKey, sig).
  2. Branch on key.asymmetricKeyType — null only for ed25519/ed448 (and rsa-pss with embedded hash).
  3. Derive the digest from the JOSE alg header for JWT verification (RS256 -> "sha256").

Example fix

// before
const ok = crypto.verify(null, data, pubKey, sig); // throws: no default digest

// after
const alg = pubKey.asymmetricKeyType === "ed25519" || pubKey.asymmetricKeyType === "ed448" ? null : "sha256";
const ok = crypto.verify(alg, data, pubKey, sig);
Defensive patterns

Strategy: validation

Validate before calling

function requiredVerifyDigest(key, requested) {
  if (requested != null) return requested;
  const t = key.asymmetricKeyType ?? key.key?.asymmetricKeyType;
  if (t === "ed25519" || t === "ed448") return null;
  throw new Error(`an explicit digest (e.g. "sha256") is required to verify with ${t} keys`);
}
const ok = crypto.verify(requiredVerifyDigest(pubKey, alg), data, pubKey, sig);

Type guard

const needsExplicitVerifyDigest = (key) => {
  const t = key.asymmetricKeyType ?? key.key?.asymmetricKeyType;
  return t !== "ed25519" && t !== "ed448" && t !== "rsa-pss";
};

Try / catch

try {
  ok = crypto.verify(digest, data, pubKey, sig);
} catch (e) {
  if (e instanceof TypeError && /no default digest/.test(e.message)) {
    throw new Error(`pass an explicit digest for key type ${pubKey.asymmetricKeyType}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: crypto.verify(null, data, rsaPubKey, sig); crypto.verify(null, data, ecPubKey, sig); ed25519-first verify helpers that always pass null.

Common situations: 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.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/dc5a8b748b0bb579. Report an issue: GitHub.