{"record":{"id":"d38580895e1c18b1","repo":"auth0/node-jsonwebtoken","slug":"alg-parameter-for-keytype-key-type-must-be","errorCode":null,"errorMessage":"\"alg\" parameter for \"${keyType}\" key type must be one of: ${allowedAlgorithms.join(', ')}.","messagePattern":"\"alg\" parameter for \"(.+?)\" key type must be one of: (.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/validateAsymmetricKey.js","lineNumber":29,"sourceCode":"  ES256: 'prime256v1',\n  ES384: 'secp384r1',\n  ES512: 'secp521r1',\n};\n\nmodule.exports = function(algorithm, key) {\n  if (!algorithm || !key) return;\n\n  const keyType = key.asymmetricKeyType;\n  if (!keyType) return;\n\n  const allowedAlgorithms = allowedAlgorithmsForKeys[keyType];\n\n  if (!allowedAlgorithms) {\n    throw new Error(`Unknown key type \"${keyType}\".`);\n  }\n\n  if (!allowedAlgorithms.includes(algorithm)) {\n    throw new Error(`\"alg\" parameter for \"${keyType}\" key type must be one of: ${allowedAlgorithms.join(', ')}.`)\n  }\n\n  /*\n   * Ignore the next block from test coverage because it gets executed\n   * conditionally depending on the Node version. Not ignoring it would\n   * prevent us from reaching the target % of coverage for versions of\n   * Node under 15.7.0.\n   */\n  /* istanbul ignore next */\n  if (ASYMMETRIC_KEY_DETAILS_SUPPORTED) {\n    switch (keyType) {\n    case 'ec':\n      const keyCurve = key.asymmetricKeyDetails.namedCurve;\n      const allowedCurve = allowedCurves[algorithm];\n\n      if (keyCurve !== allowedCurve) {\n        throw new Error(`\"alg\" parameter \"${algorithm}\" requires curve \"${allowedCurve}\".`);\n      }","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/auth0/node-jsonwebtoken/blob/b924272f29192e12926b5414546f7c5bfcc9579d/lib/validateAsymmetricKey.js#L11-L47","documentation":"When the key's type IS recognized, jsonwebtoken restricts which 'alg' header values may be paired with it (e.g. RS256/RS384/RS512 for 'rsa', ES256/384/512 for 'ec'). Throwing prevents algorithm-confusion attacks where a weak or mismatched algorithm is used with a key of a different family.","triggerScenarios":"Calling jwt.sign(payload, ecKey, { algorithm: 'RS256' }) or jwt.verify(token, rsaPublicKey, { algorithms: ['ES256'] }) — any combination where the algorithm is not in the allowed list for the detected key type.","commonSituations":"Copy-pasting sign/verify options between projects that use different key types; typo like 'rs256' (case-sensitive list); reusing an EC key where RSA algorithms are expected after a key rotation.","solutions":["Match the algorithm to the key type: RSA keys use RS*/PS*, EC keys use ES*, and pass it explicitly in options","Omit the 'algorithm' option on sign so the library picks the default for the key type","Regenerate or swap the key to the type the algorithm requires (e.g. generate an RSA key for RS256)","Check algorithm spelling/case against the allowed list in the error message"],"exampleFix":"// before\njwt.sign(payload, ecPrivateKey, { algorithm: 'RS256' });\n// after\njwt.sign(payload, ecPrivateKey, { algorithm: 'ES256' });","handlingStrategy":"validation","validationCode":"function algFitsKey(alg, key) {\n  const t = String(key.asymmetricKeyType || '');\n  const map = { rsa: /^RS/, 'rsa-pss': /^PS/, ec: /^ES/, ed25519: /^EdDSA$/ };\n  return !t || (map[t] && map[t].test(alg));\n}\nif (options.algorithm && !algFitsKey(options.algorithm, key)) throw new Error('alg ' + options.algorithm + ' does not match key type ' + key.asymmetricKeyType);","typeGuard":"function isAlgCompatible(alg, key) {\n  const t = String(key.asymmetricKeyType || '');\n  if (t === 'rsa') return /^RS(256|384|512)$/.test(alg);\n  if (t === 'rsa-pss') return /^PS(256|384|512)$/.test(alg);\n  if (t === 'ec') return /^ES(256|384|512)$/.test(alg);\n  if (t === 'ed25519') return alg === 'EdDSA';\n  return true;\n}","tryCatchPattern":"try {\n  token = jwt.sign(payload, key, { algorithm: requestedAlg });\n} catch (err) {\n  if (/must be one of/.test(err.message)) {\n    // fall back to the library default for this key type\n    token = jwt.sign(payload, key);\n  } else throw err;\n}","preventionTips":["Derive the algorithm from the key type, never hardcode it across environments","Centralize alg selection in one helper tested per key type","Watch case: algorithms are uppercase (RS256, not rs256)","On verify, list algorithms explicitly and keep them consistent with the key in use"],"tags":["jwt","algorithm-mismatch","asymmetric-key"],"backgroundTag":"jwt-algorithm-mismatch","analyzedSha":"b924272f29192e12926b5414546f7c5bfcc9579d","analyzedAt":"2026-09-02T21:29:06.876Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}