Error message
The specified key byte array is 96 bits which is not secure enough for any JWT HMAC-SHA algorithm.
Also printed as
- io.jsonwebtoken.security.WeakKeyException: The specified key byte array is 96 bits which is not secure enough for any JWT HMAC-SHA algorithm.
- io.jsonwebtoken.security.SignatureException: Unable to compute HS512 signature. Cause: The signing key's size is 256 bits which is not secure enough for the HS512 algorithm.
- io.jsonwebtoken.security.WeakKeyException: The signing key's size is 256 bits which is not secure enough for the HS512 algorithm.
The bit count reflects your key. `Keys.hmacShaKeyFor` says "…not secure enough for any JWT HMAC-SHA algorithm". Signing with an explicit algorithm the key is too short for names the algorithm: JJWT 0.12+ wraps it as "SignatureException: Unable to compute HS512 signature. Cause: The signing key's size is 256 bits…", 0.11 throws it as a `WeakKeyException` directly.
JJWT (Java) — io.jsonwebtoken.security.WeakKeyException from Keys.hmacShaKeyFor / signWith
What it means
JJWT refuses to build an HMAC key from fewer bits than the hash output of the algorithm: at least 256 bits (32 bytes) for HS256, 384 for HS384, 512 for HS512. RFC 7518 §3.2 makes this a MUST, because a short shared secret can be recovered offline by brute force from any token signed with it — after which anyone can mint valid tokens. The number in the message is the size of the bytes you supplied.
Why it happens
A human-readable secret
commonValues like `secret`, `changeme`, or a short passphrase from a tutorial are far below 32 bytes. Their length is also a hint that they were never meant for production.
Upgrading from JJWT 0.9
commonJJWT 0.9 accepted short keys passed as strings. 0.10+ enforces RFC 7518 key sizes, so the same configuration fails after an upgrade.
Key long enough for HS256, not for HS512
occasionalA 32-byte key satisfies HS256 but not HS384/HS512. `signWith(key)` picks the strongest algorithm the key allows; specifying a stronger one explicitly fails.
How to fix it
- 1.
Generate a random secret of the right size
Use a cryptographically random value (64 bytes covers all HMAC variants) and store it in a secret manager, base64-encoded.
bash # 64 random bytes, base64-encoded: enough for HS256, HS384 and HS512 openssl rand -base64 64 | tr -d '\n' - 2.
Decode the stored secret to bytes
Create the key from the decoded bytes, not from the base64 text, so that every service derives the same key.
java import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; javax.crypto.SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(System.getenv("JWT_SECRET_B64"))); String token = io.jsonwebtoken.Jwts.builder().subject("user-42").signWith(key).compact();