jwtk/jjwt · error · WeakKeyException
The RSA key size (aka modulus bit length) is bits which is…
Error message
The RSA ${keyType(signing)} key size (aka modulus bit length) is ${size} bits which is not secure enough for the ${id} algorithm. The JWT JWA Specification (RFC 7518, Section ${section}) states that RSA keys MUST have a size >= ${MIN_KEY_BIT_LENGTH} bits. Consider using the Jwts.SIG.${id}.keyPair() builder to create a KeyPair guaranteed to be secure enough for ${id}. See https://tools.ietf.org/html/rfc7518#section-${section} for more information. What it means
Thrown as WeakKeyException when an RSA signing/verification key's modulus bit length is below the minimum required by the algorithm (2048 bits for RS*/PS* per RFC 7518 sections 3.3/3.5). jjwt enforces JWA minimum key sizes to prevent insecure signatures.
Solutions
- Generate a new RSA keypair of >= 2048 bits, ideally with Jwts.SIG.RS256.keyPair().build() or openssl genrsa 2048.
- Rotate stored keys and update all verification parties with the new public key.
- If truly needed for legacy interop, use an explicit weaker configuration only in test environments (not recommended).
Example fix
// before
KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
kg.initialize(1024);
// after
KeyPair kp = Jwts.SIG.RS256.keyPair().build(); // 2048-bit by default Defensive patterns
Strategy: validation
Validate before calling
RSAPublicKey pub = (RSAPublicKey) keyPair.getPublic();
if (pub.getModulus().bitLength() < 2048) throw new IllegalStateException("RSA key too small for RS*/PS*"); Type guard
boolean strongEnough(RSAPublicKey k) { return k.getModulus().bitLength() >= 2048; } Try / catch
try { /* sign/verify */ } catch (WeakKeyException e) { throw new IllegalStateException("Rotate to a >= 2048-bit RSA key", e); } Prevention
- Always generate RSA keys with >= 2048 bits (Jwts.SIG.RSxxx.keyPair() does this).
- Audit legacy keystores for 1024-bit or smaller keys.
- Establish key-rotation policy so old weak keys are replaced.
When it happens
Trigger: Signing or verifying a JWT with an RSA key smaller than 2048 bits (e.g. legacy 1024-bit keys) with RS256/RS384/RS512/PS256/PS384/PS512 via Jwts.builder().signWith or parser verification.
Common situations: Legacy test/development keys (512/768/1024-bit) still used in production; keys generated years ago with outdated tooling; unit tests with fast small keys.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- The RSA key size (aka modulus bit length) is bits which is…
- Secret JWK value is ' ', but the length is smaller than the…
- The specified key byte array is bits which is not secure…
- ${e.getMessage()}
- EC JWK x,y coordinates do not exist on elliptic curve
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/a8f0f73879985554.
Report an issue: GitHub.
Appendix: source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/RsaSignatureAlgorithm.java:197
@Override
protected void validateKey(Key key, boolean signing) {
super.validateKey(key, signing);
if (!isRsaAlgorithmName(key)) {
throw new InvalidKeyException("Unrecognized RSA or RSASSA-PSS key algorithm name.");
}
int size = KeysBridge.findBitLength(key);
if (size < 0) return; // https://github.com/jwtk/jjwt/issues/68
if (size < MIN_KEY_BIT_LENGTH) {
String id = getId();
String section = id.startsWith("PS") ? "3.5" : "3.3";
String msg = "The RSA " + keyType(signing) + " key size (aka modulus bit length) is " + size + " bits " +
"which is not secure enough for the " + id + " algorithm. The JWT JWA Specification " +
"(RFC 7518, Section " + section + ") states that RSA keys MUST have a size >= " +
MIN_KEY_BIT_LENGTH + " bits. Consider using the Jwts.SIG." + id +
".keyPair() builder to create a KeyPair guaranteed to be secure enough for " + id + ". See " +
"https://tools.ietf.org/html/rfc7518#section-" + section + " for more information.";
throw new WeakKeyException(msg);
}
}
@Override
protected byte[] doDigest(final SecureRequest<InputStream, PrivateKey> request) {
return jca(request).withSignature(new CheckedFunction<Signature, byte[]>() {
@Override
public byte[] apply(Signature sig) throws Exception {
if (algorithmParameterSpec != null) {
sig.setParameter(algorithmParameterSpec);
}
sig.initSign(request.getKey());
return sign(sig, request.getPayload());
}
});
}
@OverrideView on GitHub (pinned to fb71496164)