jwtk/jjwt · error · InvalidKeyException
The ${keyType} key's algorithm '${alg}' does not equal a val
Error message
The ${keyType} key's algorithm '${alg}' does not equal a valid HmacSHA* algorithm name and cannot be used with ${name}. What it means
Algorithm-name guard in SignatureAlgorithm.assertValid for HMAC keys: the SecretKey's algorithm string is compared (case-insensitively, per jjwt issue #381) against the enum's JCA name and PKCS12 aliases (HmacSHA256/384/512 variants). A key whose algorithm is set to anything else (e.g. 'AES', 'DES') cannot be proven to be an HMAC key of the right family, so InvalidKeyException is thrown.
Source
Thrown at api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java:379
try {
encoded = secretKey.getEncoded();
if (encoded == null) {
throw new InvalidKeyException("The " + keyType(signing) + " key's encoded bytes cannot be null.");
}
String alg = secretKey.getAlgorithm();
if (alg == null) {
throw new InvalidKeyException("The " + keyType(signing) + " key's algorithm cannot be null.");
}
// These next checks use equalsIgnoreCase per https://github.com/jwtk/jjwt/issues/381#issuecomment-412912272
if (!HS256.jcaName.equalsIgnoreCase(alg) &&
!HS384.jcaName.equalsIgnoreCase(alg) &&
!HS512.jcaName.equalsIgnoreCase(alg) &&
!HS256.pkcs12Name.equals(alg) &&
!HS384.pkcs12Name.equals(alg) &&
!HS512.pkcs12Name.equals(alg)) {
throw new InvalidKeyException("The " + keyType(signing) + " key's algorithm '" + alg +
"' does not equal a valid HmacSHA* algorithm name and cannot be used with " + name() + ".");
}
int size = encoded.length * 8; //size in bits
if (size < this.minKeyLength) {
String msg = "The " + keyType(signing) + " key's size is " + size + " bits which " +
"is not secure enough for the " + name() + " algorithm. The JWT " +
"JWA Specification (RFC 7518, Section 3.2) states that keys used with " + name() + " MUST have a " +
"size >= " + minKeyLength + " bits (the key size must be greater than or equal to the hash " +
"output size). Consider using the " + Keys.class.getName() + " class's " +
"'secretKeyFor(SignatureAlgorithm." + name() + ")' method to create a key guaranteed to be " +
"secure enough for " + name() + ". See " +
"https://tools.ietf.org/html/rfc7518#section-3.2 for more information.";
throw new WeakKeyException(msg);
}
} finally {
if (encoded != null) {
Arrays.fill(encoded, (byte) 0);View on GitHub (pinned to fb71496164)
Solutions
- Re-wrap the secret bytes with the correct algorithm: new SecretKeySpec(encoded, "HmacSHA256") (or 384/512 to match the chosen HS* algorithm).
- Ensure the algorithm name matches one of: the enum's jcaName (e.g. HmacSHA256) or its pkcs12Name alias, case-insensitively.
- If the key genuinely is an AES or other non-HMAC key, generate a dedicated HMAC key with Keys.secretKeyFor(SignatureAlgorithm.HS256).
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java:379 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/b8392813c09dba4d.
Report an issue: GitHub.