auth0/node-jsonwebtoken · error
"alg" parameter "${algorithm}" requires curve "${allowedCurv
Error message
"alg" parameter "${algorithm}" requires curve "${allowedCurve}". What it means
For EC keys, each ES* algorithm mandates a specific NIST curve (ES256 -> P-256, ES384 -> P-384, ES512 -> P-521). jsonwebtoken compares the key's asymmetricKeyDetails.namedCurve against the required curve and throws when they differ, since Node's crypto would otherwise produce a mismatched/invalid signature length.
Source
Thrown at lib/validateAsymmetricKey.js:46
if (!allowedAlgorithms.includes(algorithm)) {
throw new Error(`"alg" parameter for "${keyType}" key type must be one of: ${allowedAlgorithms.join(', ')}.`)
}
/*
* Ignore the next block from test coverage because it gets executed
* conditionally depending on the Node version. Not ignoring it would
* prevent us from reaching the target % of coverage for versions of
* Node under 15.7.0.
*/
/* istanbul ignore next */
if (ASYMMETRIC_KEY_DETAILS_SUPPORTED) {
switch (keyType) {
case 'ec':
const keyCurve = key.asymmetricKeyDetails.namedCurve;
const allowedCurve = allowedCurves[algorithm];
if (keyCurve !== allowedCurve) {
throw new Error(`"alg" parameter "${algorithm}" requires curve "${allowedCurve}".`);
}
break;
case 'rsa-pss':
if (RSA_PSS_KEY_DETAILS_SUPPORTED) {
const length = parseInt(algorithm.slice(-3), 10);
const { hashAlgorithm, mgf1HashAlgorithm, saltLength } = key.asymmetricKeyDetails;
if (hashAlgorithm !== `sha${length}` || mgf1HashAlgorithm !== hashAlgorithm) {
throw new Error(`Invalid key for this operation, its RSA-PSS parameters do not meet the requirements of "alg" ${algorithm}.`);
}
if (saltLength !== undefined && saltLength > length >> 3) {
throw new Error(`Invalid key for this operation, its RSA-PSS parameter saltLength does not meet the requirements of "alg" ${algorithm}.`)
}
}
break;
}View on GitHub (pinned to b924272f29)
Solutions
- Regenerate the key with the matching curve: crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' }) for ES256 ('P-384' for ES384, 'P-521' for ES512)
- Or change the algorithm to match the existing curve (P-384 key -> ES384)
- Check the curve with key.asymmetricKeyDetails.namedCurve before signing
Example fix
// before
const { privateKey } = crypto.generateKeyPairSync('ec', { namedCurve: 'secp256k1' });
jwt.sign(payload, privateKey, { algorithm: 'ES256' });
// after
const { privateKey } = crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' });
jwt.sign(payload, privateKey, { algorithm: 'ES256' }); Defensive patterns
Strategy: validation
Validate before calling
const curveForAlg = { ES256: 'P-256', ES384: 'P-384', ES512: 'P-521' };
function ecCurveMatches(alg, key) {
if (!/^ES/.test(alg)) return true;
return key.asymmetricKeyDetails?.namedCurve === curveForAlg[alg];
}
if (!ecCurveMatches(alg, key)) throw new Error('Curve ' + key.asymmetricKeyDetails.namedCurve + ' does not match ' + alg); Type guard
function isEsAlgWithMatchingCurve(alg, key) {
const required = { ES256: 'P-256', ES384: 'P-384', ES512: 'P-521' }[alg];
return !required || key.asymmetricKeyDetails?.namedCurve === required;
} Try / catch
try {
return jwt.sign(payload, ecKey, { algorithm: alg });
} catch (err) {
if (/requires curve/.test(err.message)) {
const algByCurve = { 'P-256': 'ES256', 'P-384': 'ES384', 'P-521': 'ES512' };
return jwt.sign(payload, ecKey, { algorithm: algByCurve[ecKey.asymmetricKeyDetails.namedCurve] });
}
throw err;
} Prevention
- Always specify namedCurve explicitly when generating EC keys
- Generate the curve from the algorithm, not the other way around
- Log namedCurve when importing keys from KMS/HSM or OpenSSL
- Add a startup key-integrity check that pairs curve to algorithm
When it happens
Trigger: jwt.sign(payload, ecKey, { algorithm: 'ES256' }) where the EC key was generated on the P-384 or secp256k1 curve instead of prime256v1 (P-256).
Common situations: Generating EC keys without specifying namedCurve (some tooling defaults to P-384 or secp256k1); keys exported from cloud KMS or OpenSSL with a curve that doesn't match the chosen algorithm; switching algorithms from ES256 to ES384 without regenerating the key.
Related errors
- "alg" parameter for "${keyType}" key type must be one of: ${
- Unknown key type "${keyType}".
- Invalid key for this operation, its RSA-PSS parameters do no
- Invalid key for this operation, its RSA-PSS parameter saltLe
- Expected "${parameterName}" to be a plain object.
AI-assisted analysis of auth0/node-jsonwebtoken@b924272f29 (2026-09-02).
Data as JSON: /api/errors/83be1cd27b4f6487.
Report an issue: GitHub.