denoland/deno · error · DOMException
Named curve mismatch
Error message
Named curve mismatch
What it means
_validateEcNamedCurve throws DOMException DataError 'Named curve mismatch' when an EC KeyObject on one curve is converted via toCryptoKey() with an algorithm object whose namedCurve names a different curve. The polyfill first normalizes OpenSSL names (prime256v1/secp384r1/secp521r1) and WebCrypto names (P-256/P-384/P-521) to a common form, so only genuine mismatches throw — either naming style works if it is the right curve.
Source
Thrown at ext/node/polyfills/internal/crypto/keys.ts:1063
function _validateEcNamedCurve(
keyObject: AsymmetricKeyObject,
algorithm: object,
) {
const details = keyObject.asymmetricKeyDetails;
const alg = algorithm as { namedCurve?: string };
if (alg.namedCurve && details?.namedCurve) {
const curveMap: Record<string, string> = {
"prime256v1": "P-256",
"secp384r1": "P-384",
"secp521r1": "P-521",
"P-256": "P-256",
"P-384": "P-384",
"P-521": "P-521",
};
const keyCurve = curveMap[details.namedCurve] || details.namedCurve;
if (keyCurve !== alg.namedCurve) {
throw new DOMException("Named curve mismatch", "DataError");
}
}
}
function createSecretKey(
key: string | ArrayBufferView | ArrayBuffer | KeyObject | CryptoKey,
encoding?: string,
): KeyObject {
if (isCryptoKey(key)) {
if (key.type !== "secret") {
throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE(key.type, "secret");
}
return KeyObject.from(key);
}
const preparedKey = prepareSecretKey(key, encoding, true);
if (isArrayBufferView(preparedKey) || isAnyArrayBuffer(preparedKey)) {
const handle = op_node_create_secret_key(preparedKey);
return new SecretKeyObject(handle);View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Set namedCurve to the key's actual curve: 'P-256', 'P-384' or 'P-521'
- Read keyObject.asymmetricKeyDetails.namedCurve and feed that value into the algorithm object
- Centralize the curve in one constant used by both generation and conversion code
Example fix
// before
const ck = privateKey.toCryptoKey({ name: 'ECDSA', namedCurve: 'P-384' }, true, ['sign']); // key is P-256 -> throws
// after
const details = privateKey.asymmetricKeyDetails;
const ck = privateKey.toCryptoKey({ name: 'ECDSA', namedCurve: details.namedCurve }, true, ['sign']); Defensive patterns
Strategy: validation
Validate before calling
const NORMALIZE: Record<string, string> = {
prime256v1: 'P-256', secp384r1: 'P-384', secp521r1: 'P-521',
};
const details = privateKey.asymmetricKeyDetails;
if (details?.namedCurve && params.namedCurve) {
const keyCurve = NORMALIZE[details.namedCurve] ?? details.namedCurve;
if (keyCurve !== params.namedCurve) {
params = { ...params, namedCurve: keyCurve };
}
}
const ck = privateKey.toCryptoKey(params, true, ['sign']); Type guard
function namedCurveMatches(keyObject: KeyObject, namedCurve: string): boolean {
const map: Record<string, string> = {
prime256v1: 'P-256', secp384r1: 'P-384', secp521r1: 'P-521',
};
const d = keyObject.asymmetricKeyDetails?.namedCurve;
return !d || !namedCurve || (map[d] ?? d) === namedCurve;
} Try / catch
try {
ck = privateKey.toCryptoKey(params, true, usages);
} catch (e) {
if (e instanceof DOMException && e.name === 'DataError' && e.message === 'Named curve mismatch') {
const actual = privateKey.asymmetricKeyDetails.namedCurve;
ck = privateKey.toCryptoKey({ ...params, namedCurve: actual }, true, usages);
} else throw e;
} Prevention
- Read the curve from asymmetricKeyDetails instead of trusting config
- Keep one curve constant used by both generation and import
- Accept both OpenSSL and WebCrypto curve spellings in config, then normalize
When it happens
Trigger: generateKeyPairSync('ec', { namedCurve: 'prime256v1' }).privateKey.toCryptoKey({ name: 'ECDSA', namedCurve: 'P-384' }, true, ['sign']) — key is P-256, params say P-384.
Common situations: Curve configured in one place for key generation and in another for import/use; a shared default namedCurve drifting from the keys actually issued; compliance-mandated migration to P-384 while old P-256 keys are still converted by the same code.
Related errors
- PBKDF2 keys are not extractable
- HKDF keys are not extractable
- Invalid key type
- operation not supported for this keytype
- Invalid key type
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/4a7e6cd74ddf1650.
Report an issue: GitHub.