gchq/CyberChef · error · OperationError
Error: Have you entered the key correctly? The key should be
Error message
Error: Have you entered the key correctly? The key should be either the secret for HMAC algorithms or the PEM-encoded private key for RSA and ECDSA.
${err} What it means
Thrown by JWT Sign when jsonwebtoken's sign() rejects. The hint in the message points at the two dominant causes: a key that does not match the chosen algorithm, or a header argument that is not valid JSON. sign() throws for key/algorithm mismatch, malformed PEM, invalid header JSON, or unsupported algorithm.
Source
Thrown at src/core/operations/JWTSign.mjs:62
}
];
}
/**
* @param {JSON} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [key, algorithm, header] = args;
try {
return jwt.sign(input, key, {
algorithm: algorithm === "None" ? "none" : algorithm,
header: JSON.parse(header || "{}")
});
} catch (err) {
throw new OperationError(`Error: Have you entered the key correctly? The key should be either the secret for HMAC algorithms or the PEM-encoded private key for RSA and ECDSA.
${err}`);
}
}
}
export default JWTSign;
View on GitHub (pinned to 4290ea7539)
Solutions
- Match the key to the algorithm: shared secret for HMAC, PEM private key for RSA/ECDSA.
- Ensure the header argument is strict JSON (double quotes, parseable by JSON.parse).
- For RSA/ECDSA, supply a valid unencrypted PEM private key.
- Verify the algorithm name is one jsonwebtoken supports.
Example fix
// before: HMAC algorithm but a PEM key
chef.JWTSign(payload, { key: pemPrivateKey, algorithm: 'HS256', header: '{}' });
// after: algorithm matches the key
chef.JWTSign(payload, { key: 'my-secret', algorithm: 'HS256', header: '{}' }); Defensive patterns
Strategy: validation
Validate before calling
function validateJwtSignArgs(key, algorithm, header) {
if (algorithm && algorithm !== 'None')
JSON.parse(header || '{}'); // header must be JSON
const isPem = /-----BEGIN/.test(String(key));
if (/^HS/.test(algorithm) && isPem) throw new Error('HMAC needs a shared secret, not a PEM');
if (/^(RS|ES|PS)/.test(algorithm) && !isPem) throw new Error('RSA/ECDSA needs a PEM private key');
} Type guard
function keyMatchesAlgorithm(key, algorithm) {
const isPem = /-----BEGIN [A-Z ]*PRIVATE KEY-----/.test(String(key));
return /^HS|^none$/i.test(algorithm) ? !isPem : isPem;
} Try / catch
try {
return chef.JWTSign(input, { key, algorithm, header });
} catch (e) {
if (/entered the key correctly/.test(e.message))
throw new Error('Algorithm/key mismatch or bad header JSON');
throw e;
} Prevention
- Match HMAC algorithms with a secret, RSA/ECDSA with a PEM private key.
- Keep the header strict JSON (double quotes).
- Remember 'None' maps to 'none'.
When it happens
Trigger: Selecting an HMAC algorithm (HS256) but supplying a PEM private key; selecting RSA/ECDSA but supplying a plain-text secret; header argument that is not parseable JSON (e.g. '{alg: x}'); a malformed or encrypted PEM; an algorithm string the library does not recognise.
Common situations: Copying a key from the wrong format. Forgetting that 'None' maps to 'none'. Passing a header with single quotes or trailing commas. Using an ECDSA key with an RSA algorithm selection.
Related errors
- ${verified.message}
- Input is not a JSON Web Key
- Invalid JWK format
- Unsupported JWK key type '${inputJson.kty}'
- ${err}
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/9c78b2d01fd5171d.
Report an issue: GitHub.