jwtk/jjwt · error · InvalidKeyException
MAC ${keyType} keys must be SecretKey instances. Specified
Error message
MAC ${keyType} keys must be SecretKey instances. Specified key is of type ${k.getClass().getName()} What it means
InvalidKeyException from DefaultMacAlgorithm.validateKey when the supplied Key is not a javax.crypto.SecretKey instance. MAC (HMAC) algorithms require symmetric secret keys, not RSA/EC public or private keys.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/DefaultMacAlgorithm.java:161
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);
}
if (k instanceof Password) {
String msg = "Passwords are intended for use with key derivation algorithms only.";
throw new InvalidKeyException(msg);
}
final SecretKey key = (SecretKey) k;
final String id = getId();
assertAlgorithmName(key, signing);
int size = KeysBridge.findBitLength(key);
// We can only perform length validation if key bit length is available
// per https://github.com/jwtk/jjwt/issues/478 and https://github.com/jwtk/jjwt/issues/619
// so return early if we can't:View on GitHub (pinned to fb71496164)
Solutions
- Use a SecretKey: Keys.hmacShaKeyFor(secretBytes) or Jwts.SIG.HS256.key().build().
- If you have an RSA/EC key pair, switch to the matching asymmetric algorithm (RS256/ES256) instead of HS256.
- Check the keystore lookup so you retrieve the intended secret-key entry.
- Guard with (key instanceof SecretKey) before calling signWith/verifyWith.
Example fix
// before KeyPair kp = Keys.keyPairFor(SignatureAlgorithm.RS256); Jwts.builder().signWith(kp.getPrivate(), Jwts.SIG.HS256); // wrong key type // after SecretKey key = Keys.hmacShaKeyFor(secretBytes); Jwts.builder().signWith(key, Jwts.SIG.HS256);
Defensive patterns
Strategy: type-guard
Validate before calling
static SecretKey requireSecretKey(Key k) {
if (!(k instanceof SecretKey))
throw new IllegalArgumentException("HMAC requires a SecretKey, got " + k.getClass().getName());
return (SecretKey) k;
} Type guard
boolean isSecretKey(Key k) { return k instanceof javax.crypto.SecretKey; } Try / catch
try {
return Jwts.builder().signWith(key, Jwts.SIG.HS256).compact();
} catch (InvalidKeyException e) {
if (e.getMessage().contains("SecretKey instances"))
throw new IllegalStateException("Asymmetric key used with MAC algorithm");
throw e;
} Prevention
- Pair algorithms and key types: HS* with SecretKey, RS*/PS*/ES* with KeyPair
- Keystore lookups: confirm getEntry returns SecretKeyEntry, not PrivateKeyEntry
- Keep separate typed fields for MAC keys vs signing key pairs
When it happens
Trigger: Calling signWith(rsaPrivateKey, HS256) or verifyWith(ecPublicKey) with an HMAC algorithm; passing a java.security.Key from a keystore that is a PrivateKey.
Common situations: Mixing asymmetric signing code (RS256) with HMAC algorithm configuration; loading the wrong key entry from a keystore; copy-pasting algorithm constants while reusing key variables.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- The ${keyType(signing)} key's algorithm cannot be null or em
- The ${keyType(signing)} key's algorithm '${name}' does not e
- MAC ${keyType} key cannot be null.
- 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/9f60f07d99303ad1.
Report an issue: GitHub.