jwtk/jjwt · error · InvalidKeyException

JWT standard signing algorithms require either 1) a…

Error message

JWT standard signing algorithms require either 1) a SecretKey for HMAC-SHA algorithms or 2) a private RSAKey for RSA algorithms or 3) a private ECKey for Elliptic Curve algorithms.  The specified key is of type ${keyClassName}

What it means

Error "JWT standard signing algorithms require either 1) a SecretKey for HMAC-SHA algorithms or 2) a private RSAKey for RSA algorithms or 3) a private ECKey for Elliptic Curve algorithms. The specified key is of type ${keyClassName}" thrown in jwtk/jjwt.

Solutions

  1. Supply a key of one of the supported types: SecretKey for HMAC (HS*), RSAKey PrivateKey for RSA (RS*/PS*), or ECKey PrivateKey for EC (ES*).
  2. Wrap raw secret bytes in a SecretKeySpec with an HmacSHA* algorithm name so the type matches family 1.
  3. Use Keys.secretKeyFor / Keys.keyPairFor to generate keys guaranteed to match the expected type hierarchy.
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java:581 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/546acdc8ea615fdb. Report an issue: GitHub.

Appendix: source

Thrown at api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java:581

     *
     * @param key the key to inspect
     * @return the recommended signature algorithm to be used with the specified key
     * @throws InvalidKeyException for any key that does not match the heuristics and requirements documented above,
     *                             since that inevitably means the Key is either insufficient or explicitly disallowed by the JWT specification.
     * @since 0.10.0
     */
    public static SignatureAlgorithm forSigningKey(Key key) throws InvalidKeyException {

        if (key == null) {
            throw new InvalidKeyException("Key argument cannot be null.");
        }

        if (!(key instanceof SecretKey ||
                (key instanceof PrivateKey && (key instanceof ECKey || key instanceof RSAKey)))) {
            String msg = "JWT standard signing algorithms require either 1) a SecretKey for HMAC-SHA algorithms or " +
                    "2) a private RSAKey for RSA algorithms or 3) a private ECKey for Elliptic Curve algorithms.  " +
                    "The specified key is of type " + key.getClass().getName();
            throw new InvalidKeyException(msg);
        }

        if (key instanceof SecretKey) {

            SecretKey secretKey = (SecretKey) key;
            byte[] encoded = EMPTY_BYTES;
            int bitLength;
            try {
                encoded = secretKey.getEncoded();
                bitLength = io.jsonwebtoken.lang.Arrays.length(encoded) * Byte.SIZE;
            } finally {
                Arrays.fill(encoded, (byte) 0);
            }

            for (SignatureAlgorithm alg : PREFERRED_HMAC_ALGS) {
                // ensure compatibility check is based on key length. See https://github.com/jwtk/jjwt/issues/381
                if (bitLength >= alg.minKeyLength) {
                    return alg;

View on GitHub (pinned to fb71496164)