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

  1. Re-wrap the secret bytes with the correct algorithm: new SecretKeySpec(encoded, "HmacSHA256") (or 384/512 to match the chosen HS* algorithm).
  2. Ensure the algorithm name matches one of: the enum's jcaName (e.g. HmacSHA256) or its pkcs12Name alias, case-insensitively.
  3. 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.