jwtk/jjwt · critical · WeakKeyException
The specified key byte array is bits which is not secure…
Error message
The specified key byte array is bits which is not secure enough for any JWT HMAC-SHA algorithm. The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HMAC-SHA algorithms MUST have a size >= 256 bits (the key size must be greater than or equal to the hash output size). Consider using the Jwts.SIG.HS256.key() builder (or HS384.key() or HS512.key()) to create a key guaranteed to be secure enough for your preferred HMAC-SHA algorithm. See https://tools.ietf.org/html/rfc7518#section-3.2 for more information.
What it means
Keys.hmacShaKeyFor throws WeakKeyException when the supplied key byte array is shorter than 256 bits (32 bytes), which RFC 7518 §3.2 forbids for JWT HMAC-SHA algorithms. This is a deliberate security guard — weak keys make MAC forgery feasible.
Solutions
- Generate a key of at least 256 bits: Keys.secretKeyFor(SignatureAlgorithm.HS256) or Jwts.SIG.HS256.key().build()
- Use a random secret of >= 32 bytes, e.g. Base64 of 32+ random bytes
- Verify key length before calling: if (bytes.length < 32) fail at startup
- Persist the generated strong key securely (secret manager, vault) rather than a short string
Example fix
// before
SecretKey key = Keys.hmacShaKeyFor("secret".getBytes()); // WeakKeyException
// after
SecretKey key = Keys.secretKeyFor(io.jsonwebtoken.SignatureAlgorithm.HS256);
String encoded = Base64.getEncoder().encodeToString(key.getEncoded()); // store securely Defensive patterns
Strategy: validation
Validate before calling
if (secretBytes == null || secretBytes.length < 32) {
throw new IllegalStateException("JWT HMAC secret must be at least 256 bits (32 bytes)");
} Try / catch
try {
key = Keys.hmacShaKeyFor(secretBytes);
} catch (WeakKeyException e) {
throw new IllegalStateException("Refusing weak JWT secret; generate with Keys.secretKeyFor(HS256)", e);
} Prevention
- Generate secrets with Keys.secretKeyFor(SignatureAlgorithm.HS256) or a CSPRNG of >= 32 bytes
- Never use passwords, names, or short literals as HMAC secrets
- Store generated keys in a secret manager and rotate securely
- Add a startup length check so weak keys fail before serving traffic
When it happens
Trigger: Calling Keys.hmacShaKeyFor(bytes) where bytes.length * 8 < 512 bits fails the strongest checks and anything below 256 bits triggers this error — practically, passing a secret shorter than 32 bytes (e.g. "mysecret", a short password, or a truncated Base64 blob).
Common situations: Using a human-readable password as the JWT secret, hard-coded short demo secrets in production, or an env var silently cut off / partially loaded.
Related errors
- The key's size is bits which is not secure enough for the…
- The RSA key size (aka modulus bit length) is bits which is…
- EC JWK x,y coordinates do not exist on elliptic curve
- MAC key cannot be null.
- MAC keys must be SecretKey instances. Specified key is of…
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/93c6286c099513b0.
Report an issue: GitHub.
Appendix: source
Thrown at api/src/main/java/io/jsonwebtoken/security/Keys.java:83
int bitLength = bytes.length * 8;
//Purposefully ordered higher to lower to ensure the strongest key possible can be generated.
if (bitLength >= 512) {
return new SecretKeySpec(bytes, "HmacSHA512");
} else if (bitLength >= 384) {
return new SecretKeySpec(bytes, "HmacSHA384");
} else if (bitLength >= 256) {
return new SecretKeySpec(bytes, "HmacSHA256");
}
String msg = "The specified key byte array is " + bitLength + " bits which " +
"is not secure enough for any JWT HMAC-SHA algorithm. The JWT " +
"JWA Specification (RFC 7518, Section 3.2) states that keys used with HMAC-SHA algorithms MUST have a " +
"size >= 256 bits (the key size must be greater than or equal to the hash " +
"output size). Consider using the Jwts.SIG.HS256.key() builder (or HS384.key() " +
"or HS512.key()) to create a key guaranteed to be secure enough for your preferred HMAC-SHA " +
"algorithm. See https://tools.ietf.org/html/rfc7518#section-3.2 for more information.";
throw new WeakKeyException(msg);
}
/**
* <p><b>Deprecation Notice</b></p>
*
* <p>As of JJWT 0.12.0, symmetric (secret) key algorithm instances can generate a key of suitable
* length for that specific algorithm by calling their {@code key()} builder method directly. For example:</p>
*
* <pre><code>
* {@link Jwts.SIG#HS256}.key().build();
* {@link Jwts.SIG#HS384}.key().build();
* {@link Jwts.SIG#HS512}.key().build();
* </code></pre>
*
* <p>Call those methods as needed instead of this static {@code secretKeyFor} helper method - the returned
* {@link KeyBuilder} allows callers to specify a preferred Provider or SecureRandom on the builder if
* desired, whereas this {@code secretKeyFor} method does not. Consequently this helper method will be removed
* before the 1.0 release.</p>View on GitHub (pinned to fb71496164)