auth0/node-jsonwebtoken · error
secretOrPrivateKey has a minimum key size of 2048 bits for $
Error message
secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg} What it means
For RS/PS algorithms, jwt.sign() performs a post-signature length check: an RSA signature shorter than 256 bytes implies a modulus smaller than 2048 bits, which the library rejects as insecure. This protects against weak keys; it can be bypassed with the allowInsecureKeySizes option (or is unnecessary on Node 15+, which enforces key size at crypto level).
Source
Thrown at sign.js:249
jws.createSign({
header: header,
privateKey: secretOrPrivateKey,
payload: payload,
encoding: encoding
}).once('error', callback)
.once('done', function (signature) {
// TODO: Remove in favor of the modulus length check before signing once node 15+ is the minimum supported version
if(!options.allowInsecureKeySizes && /^(?:RS|PS)/.test(header.alg) && signature.length < 256) {
return callback(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`))
}
callback(null, signature);
});
} else {
let signature = jws.sign({header: header, payload: payload, secret: secretOrPrivateKey, encoding: encoding});
// TODO: Remove in favor of the modulus length check before signing once node 15+ is the minimum supported version
if(!options.allowInsecureKeySizes && /^(?:RS|PS)/.test(header.alg) && signature.length < 256) {
throw new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${header.alg}`)
}
return signature
}
};
View on GitHub (pinned to b924272f29)
Solutions
- Generate a new RSA key of at least 2048 bits: openssl genrsa -out key.pem 2048 (4096 preferred)
- Set options.allowInsecureKeySizes: true only for legacy/testing, never in production
- On Node 15+, rely on native enforcement — upgrade the key regardless, since Node will also reject short keys
- Rotate the key pair and update all verifiers with the new public key
Example fix
// before
openssl genrsa -out key.pem 1024
jwt.sign(payload, key, { algorithm: 'RS256' });
// after
openssl genrsa -out key.pem 2048
jwt.sign(payload, key, { algorithm: 'RS256' }); Defensive patterns
Strategy: validation
Validate before calling
const { createPublicKey } = require('crypto');
function rsaKeyBitsOk(pem) {
const key = createPublicKey(pem);
const bits = key.asymmetricKeyDetails?.modulusLength;
return bits === undefined || bits >= 2048;
}
if (!rsaKeyBitsOk(privateKey)) throw new Error('RSA key must be >= 2048 bits'); Type guard
function hasSufficientRsaModulus(keyObj) {
const bits = keyObj?.asymmetricKeyDetails?.modulusLength;
return bits === undefined || bits >= 2048;
} Try / catch
try {
return jwt.sign(payload, key, { algorithm: 'RS256' });
} catch (err) {
if (/minimum key size of 2048/.test(err.message)) {
throw new Error('Refusing to sign with weak RSA key; regenerate at 2048+ bits');
}
throw err;
} Prevention
- Generate all RSA keys at 2048+ bits and enforce it in key-rotation tooling
- Audit legacy key stores for modulusLength < 2048 and rotate them
- Never set allowInsecureKeySizes in production configuration
- Fail CI/startup key checks on small moduli rather than at first sign attempt
When it happens
Trigger: jwt.sign(payload, smallRsaKeyPem, { algorithm: 'RS256' }) with a 1024-bit (or smaller) RSA key; verification-side equivalents where the private key used was generated with -b 1024.
Common situations: Old RSA keys generated years ago at 1024 bits; test fixtures with tiny keys; OpenSSL defaults changed over versions so legacy automation still emits 1024-bit keys; copying sample keys from old tutorials.
Related errors
- Unknown key type "${keyType}".
- "alg" parameter for "${keyType}" key type must be one of: ${
- "alg" parameter "${algorithm}" requires curve "${allowedCurv
- Invalid key for this operation, its RSA-PSS parameters do no
- Invalid key for this operation, its RSA-PSS parameter saltLe
AI-assisted analysis of auth0/node-jsonwebtoken@b924272f29 (2026-09-02).
Data as JSON: /api/errors/a6d995fb15916676.
Report an issue: GitHub.