denoland/deno · error · TypeError
operation not supported for this keytype
Error message
operation not supported for this keytype
What it means
One-shot crypto.verify() explicitly rejects x25519, x448, and dh keys with TypeError("operation not supported for this keytype") — these are key-exchange key types with no verification operation. The branch runs after ed25519/ed448 handling and before digest selection, so it fires regardless of the algorithm argument.
Source
Thrown at ext/node/polyfills/internal/crypto/sig.ts:561
}
result = op_node_verify_ed25519(handle, dataBytes, signature);
} else if (keyType === "ed448") {
const keyOpts = typeof key === "object" && key !== null &&
!(ObjectPrototypeIsPrototypeOf(KeyObject.prototype, key))
? key as Record<string, unknown>
: null;
const ctx = keyOpts?.context;
if (
ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, ctx) &&
ctx.length > 0
) {
throw new TypeError("Context parameter is unsupported");
}
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" &&View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Verify only with signing keys: ed25519, rsa, ecdsa (ec), dsa, or rsa-pss.
- Check key.asymmetricKeyType (or the JWK kty/crv/use) before calling and reject exchange keys with a clear error.
- When generating keys for signature flows, use generateKeyPair("ed25519") or rsa — never x25519/x448/dh.
Example fix
// before
const { publicKey } = crypto.generateKeyPairSync("x25519");
crypto.verify(null, data, publicKey, sig); // throws: operation not supported for this keytype
// after
const { publicKey } = crypto.generateKeyPairSync("ed25519");
crypto.verify(null, data, publicKey, sig); Defensive patterns
Strategy: type-guard
Validate before calling
const SIGNING_KEY_TYPES = new Set(["rsa", "rsa-pss", "ec", "ed25519", "ed448", "dsa"]);
function assertVerifyKey(key) {
const t = key.asymmetricKeyType;
if (!SIGNING_KEY_TYPES.has(t)) {
throw new Error(`cannot verify with key type "${t}" (exchange keys cannot verify)`);
}
}
assertVerifyKey(pubKey);
const ok = crypto.verify(alg, data, pubKey, sig); Type guard
const isSigningKey = (key) => {
const t = key.asymmetricKeyType;
return t !== "x25519" && t !== "x448" && t !== "dh";
}; Try / catch
try {
ok = crypto.verify(alg, data, pubKey, sig);
} catch (e) {
if (e instanceof TypeError && /not supported for this keytype/.test(e.message)) {
throw new Error(`key of type ${pubKey.asymmetricKeyType} cannot verify signatures`);
}
throw e;
} Prevention
- When selecting from a JWKS, filter by use: "sig" and correct crv — X25519 and Ed25519 are both OKP.
- Never reuse ECDH (x25519/x448) or DH pairs for signing or verification.
- Check key.asymmetricKeyType before routing keys into sign/verify code.
When it happens
Trigger: crypto.verify(null, data, sig, x25519KeyObject); a DH public key from generateKeyPair("dh") used for verification; picking an Enc-key (OKP X25519) from a JWKS when an Ed25519 Sig-key was intended.
Common situations: Key-type confusion in JWT libraries between OKP curves (X25519 for ECDH vs Ed25519 for signatures); mTLS code reusing an ECDH key pair for signing; JWKS selection by kty only without checking crv/use.
Related errors
- ERR_INVALID_ARG_TYPE
- no default digest
- ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_ARG_VALUE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/adee723317e877c6.
Report an issue: GitHub.