denoland/deno · error · Error

operation not supported for this keytype

Error message

operation not supported for this keytype

What it means

checkUnsupportedKeyType (cipher.ts:778) runs at the top of privateEncrypt, privateDecrypt, publicEncrypt and publicDecrypt. If the key's asymmetricKeyType is one of rsa-pss, dsa, ec, ed25519, ed448, x25519 or x448, it throws the plain Error 'operation not supported for this keytype'. These four operations are RSA primitives; the blocklist mirrors the key types OpenSSL refuses for RSA padding schemes.

Source

Thrown at ext/node/polyfills/internal/crypto/cipher.ts:778

  }
}

const ENCRYPT_UNSUPPORTED_KEY_TYPES = new SafeSet([
  "rsa-pss",
  "dsa",
  "ec",
  "ed25519",
  "ed448",
  "x25519",
  "x448",
]);

function checkUnsupportedKeyType(key) {
  const keyType = isKeyObject(key)
    ? key.asymmetricKeyType
    : key?.key?.asymmetricKeyType;
  if (keyType && SetPrototypeHas(ENCRYPT_UNSUPPORTED_KEY_TYPES, keyType)) {
    throw new Error("operation not supported for this keytype");
  }
}

const WEBCRYPTO_SHA_HYPHEN_RE = new SafeRegExp("^(sha)-(?!3-)");

function normalizeOaepHash(hash: unknown): string | undefined {
  if (hash === undefined) return undefined;
  if (typeof hash !== "string") {
    throw new ERR_INVALID_ARG_TYPE("oaepHash", "string", hash);
  }
  if (!hash) return undefined;
  // Normalize to lowercase and strip WebCrypto-style hyphens
  // (e.g. "SHA-256" -> "sha256") but keep sha3/sha512 sub-variants
  // (e.g. "sha3-256", "sha512-224") intact.
  const normalized = StringPrototypeReplace(
    StringPrototypeToLowerCase(hash),
    WEBCRYPTO_SHA_HYPHEN_RE,
    "$1",

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Use an RSA key pair (createPublicKey/createPrivateKey over PEM/PKCS#8) for publicEncrypt/privateDecrypt
  2. For EC/Ed25519/Ed448 material, switch to the operations those keys support: sign/verify (ECDSA/EdDSA)
  3. For x25519/x448, use crypto.diffieHellman({ privateKey, publicKey }) instead of encrypt/decrypt
  4. If the key is rsa-pss, load an rsa (PKCS#1) key instead — rsa-pss is on the reject list

Example fix

// before
const { publicKey } = generateKeyPairSync('ed25519');
publicEncrypt(publicKey, data); // operation not supported for this keytype

// after
const { publicKey, privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048 });
const ct = publicEncrypt(publicKey, data);
const pt = privateDecrypt(privateKey, ct);
Defensive patterns

Strategy: type-guard

Validate before calling

import { isKeyObject } from 'node:crypto';
function assertRsaKeyForEncrypt(key) {
  const t = isKeyObject(key) ? key.asymmetricKeyType : key?.key?.asymmetricKeyType;
  if (t && t !== 'rsa') throw new TypeError(`key type ${t} is not usable for RSA encrypt/decrypt`);
}

Type guard

function usableForRsaOps(key) {
  const t = key?.asymmetricKeyType ?? key?.key?.asymmetricKeyType;
  return t == null || t === 'rsa';
}

Try / catch

try { publicEncrypt(key, data); } catch (e) { if (e.message === 'operation not supported for this keytype') { /* fetch/generate an RSA key instead */ } else throw e; }

Prevention

When it happens

Trigger: crypto.publicEncrypt(ed25519PublicKey, data); crypto.privateDecrypt({ key: ecKey }, ct); loading an rsa-pss key from a certificate and calling publicDecrypt; passing an x25519 key from an ECDH flow into RSA encrypt/decrypt.

Common situations: Mixing WebCrypto-generated Ed25519/EC key pairs with node:crypto RSA APIs; keys provisioned for signing reused for encryption; certificate-based key loading where the cert carries an EC or rsa-pss key.

Related errors


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