jwtk/jjwt · error · InvalidKeyException
The ${keyType(signing)} key's algorithm '${name}' does not e
Error message
The ${keyType(signing)} key's algorithm '${name}' does not equal a valid HmacSHA* algorithm name or PKCS12 OID and cannot be used with ${getId()}. What it means
InvalidKeyException from DefaultMacAlgorithm.assertAlgorithmName when the key's JCA algorithm name is present but is neither a valid HmacSHA* name nor a PKCS12 OID matching the JWA standard MAC algorithm being used, and the key is not a 'generic secret'. Only applies to JWA-standard algorithms (HS256/HS384/HS512).
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/DefaultMacAlgorithm.java:144
public SecretKeyBuilder key() {
return new DefaultSecretKeyBuilder(getJcaName(), getKeyBitLength());
}
private void assertAlgorithmName(SecretKey key, boolean signing) {
String name = key.getAlgorithm();
if (!Strings.hasText(name)) {
String msg = "The " + keyType(signing) + " key's algorithm cannot be null or empty.";
throw new InvalidKeyException(msg);
}
// We can ignore key name assertions for generic secrets, because HSM module key algorithm names
// don't always align with JCA standard algorithm names
boolean generic = KeysBridge.isGenericSecret(key);
//assert key's jca name is valid if it's a JWA standard algorithm:
if (!generic && isJwaStandard() && !isJwaStandardJcaName(name)) {
throw new InvalidKeyException("The " + keyType(signing) + " key's algorithm '" + name +
"' does not equal a valid HmacSHA* algorithm name or PKCS12 OID and cannot be used with " +
getId() + ".");
}
}
@Override
protected void validateKey(Key k, boolean signing) {
final String keyType = keyType(signing);
if (k == null) {
throw new IllegalArgumentException("MAC " + keyType + " key cannot be null.");
}
if (!(k instanceof SecretKey)) {
String msg = "MAC " + keyType + " keys must be SecretKey instances. Specified key is of type " +
k.getClass().getName();
throw new InvalidKeyException(msg);
}View on GitHub (pinned to fb71496164)
Solutions
- Use a key whose algorithm matches the MAC algorithm: new SecretKeySpec(bytes, "HmacSHA256") with HS256.
- Create the key with Keys.hmacShaKeyFor(bytes) or Jwts.SIG.HS256.key().build().
- Use a distinct signing key instead of reusing an AES encryption key.
- If the key is truly a generic secret from an HSM, ensure KeysBridge recognizes it as generic (correct algorithm naming) or use a standard-named key.
Example fix
// before SecretKey key = new SecretKeySpec(rawBytes, "AES"); JwtParser p = Jwts.parser().verifyWith(key).build(); // HS256 // after SecretKey key = Keys.hmacShaKeyFor(rawBytes); // -> HmacSHA256 sized key JwtParser p = Jwts.parser().verifyWith(key).build();
Defensive patterns
Strategy: validation
Validate before calling
static boolean isHmacNamedKey(Key k, String macJcaName) {
String n = k == null ? null : k.getAlgorithm();
return n != null && n.replace("-", "").equalsIgnoreCase(macJcaName.replace("-", ""));
}
// require isHmacNamedKey(key, "HmacSHA256") before HS256 Type guard
boolean matchesMacAlg(SecretKey k, MacAlgorithm alg) {
return k.getAlgorithm() != null && k.getAlgorithm().toUpperCase().contains("HMACSHA");
} Try / catch
try {
return parser.verifyWith(key).build().parseSignedClaims(jwt);
} catch (InvalidKeyException e) {
logger.error("Key algorithm '{}' not usable with HS256; rebuilding key", key.getAlgorithm());
return parser.verifyWith(Keys.hmacShaKeyFor(key.getEncoded())).build().parseSignedClaims(jwt);
} Prevention
- Create MAC keys only via Keys.hmacShaKeyFor or Jwts.SIG.HS*.key().build()
- Never reuse AES content-encryption keys for JWT signing
- Verify keystore-derived keys are secret keys with HmacSHA* names
- Match algorithm name to the HS variant (HmacSHA256 <-> HS256)
When it happens
Trigger: Passing a SecretKeySpec with algorithm "AES" (e.g. a content-encryption key) to signWith/verifyWith HS256; a key named "HSMKEY" from a provider that is not flagged as a generic secret; using an HmacSHA256 key with the HS384 algorithm.
Common situations: Reusing an AES key object for JWT signing; keys loaded from PKCS#12 keystores with OID names that don't match; provider-specific algorithm naming that isn't recognized as a generic secret.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- The ${keyType(signing)} key's algorithm cannot be null or em
- MAC ${keyType} key cannot be null.
- MAC ${keyType} keys must be SecretKey instances. Specified
- SecretKey byte array cannot be null.
- The specified key byte array is bits which is not secure en
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/3018ee6587179f8b.
Report an issue: GitHub.