denoland/deno · error · TypeError
Invalid EC curve name
Error message
Invalid EC curve name
What it means
A TypeError thrown by ECDH.convertKey() when the native op_node_ecdh_encode_pubkey op rejects the curve name with 'Unsupported curve'. Unlike the ECDH constructor (which validates against a JS curve table), convertKey only checks that curve is a string, then hands it straight to the crypto backend; if the backend has no implementation for that curve you get this error instead of the constructor's 'invalid curve'.
Source
Thrown at ext/node/polyfills/internal/crypto/diffiehellman.ts:1420
compress = false;
} else {
throw new ERR_CRYPTO_ECDH_INVALID_FORMAT(format);
}
} else {
compress = false;
}
let result;
try {
result = Buffer.from(
op_node_ecdh_encode_pubkey(curve, buf, compress),
);
} catch (e) {
if (
ObjectPrototypeIsPrototypeOf(TypeErrorPrototype, e) &&
(e as Error).message === "Unsupported curve"
) {
throw new TypeError("Invalid EC curve name");
}
throw new Error("Failed to convert Buffer to EC_POINT");
}
if (format === "hybrid") {
// Hybrid format: same as uncompressed but first byte is 06 or 07
// Get compressed form to determine parity
const compressedBuf = Buffer.from(
op_node_ecdh_encode_pubkey(curve, buf, true),
);
// compressed first byte is 02 (even) or 03 (odd)
// hybrid first byte is 06 (even) or 07 (odd)
result[0] = compressedBuf[0] + 4;
}
if (outputEncoding && outputEncoding !== "buffer") {
// deno-lint-ignore deno-internal/prefer-primordials -- Buffer.prototype.toString(encoding) has no primordial
return result.toString(outputEncoding);View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Use a curve the backend implements: 'prime256v1' (secp256r1), 'secp384r1', 'secp521r1', or 'X25519'
- Print/inspect the exact curve string for typos or stray whitespace before the call
- If you truly need an unsupported curve, generate the key material with another tool and pass raw buffers, or pick a supported equivalent curve and re-key
Example fix
// before const out = crypto.ECDH.convertKey(key, 'brainpoolP256r1'); // after const out = crypto.ECDH.convertKey(key, 'prime256v1');
Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = new Set(['prime256v1', 'secp256r1', 'secp384r1', 'secp521r1', 'X25519']);
if (!SUPPORTED.has(curve)) {
throw new RangeError(`unsupported curve '${curve}'; supported: ${[...SUPPORTED].join(', ')}`);
}
const out = crypto.ECDH.convertKey(key, curve, inputEncoding, outputEncoding, format); Try / catch
catch (e) { if (e instanceof TypeError && e.message === 'Invalid EC curve name') { /* surface a config error pointing at the curve name */ } throw e; } Prevention
- Centralize curve names as constants instead of free-form strings
- Trim/normalize curve strings from config files before use
- Check curve support at startup rather than mid-handshake
When it happens
Trigger: ECDH.convertKey(key, 'brainpoolP256r1') or any curve name the native layer does not implement (e.g. brainpool, made-up names, or a typo like 'secp256r1x'), even though the string passes validateString.
Common situations: Migrating code from OpenSSL or BouncyCastle that uses brainpool or other exotic curves; typos in curve names; scripts that worked on Node builds with fuller OpenSSL curve support and are re-run under a runtime with a smaller curve set.
Related errors
- ERR_CRYPTO_ECDH_INVALID_FORMAT
- ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY
- Invalid key pair
- Failed to get ECDH private key
- Failed to get ECDH public key
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/2c3d274bcbc74b7d.
Report an issue: GitHub.