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

  1. Verify only with signing keys: ed25519, rsa, ecdsa (ec), dsa, or rsa-pss.
  2. Check key.asymmetricKeyType (or the JWK kty/crv/use) before calling and reject exchange keys with a clear error.
  3. 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 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


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