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

  1. Use a key whose algorithm matches the MAC algorithm: new SecretKeySpec(bytes, "HmacSHA256") with HS256.
  2. Create the key with Keys.hmacShaKeyFor(bytes) or Jwts.SIG.HS256.key().build().
  3. Use a distinct signing key instead of reusing an AES encryption key.
  4. 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

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


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/3018ee6587179f8b. Report an issue: GitHub.