jwtk/jjwt · error · InvalidKeyException

keys must be RSAKey instances.

Error message

${familyName} ${keyType} keys must be RSAKey instances.

What it means

Type guard in SignatureAlgorithm.assertValid: for RSA algorithms (RS256/384/512, PS256/384/512), the key must implement java.security.interfaces.RSAKey so the modulus bit length can be checked. A non-RSA key (e.g. an ECKey or SecretKey) reaching this branch throws InvalidKeyException.

Solutions

  1. Supply an RSA key pair generated with Keys.keyPairFor(SignatureAlgorithm.RS256) or equivalent, at least 2048-bit modulus.
  2. If the key is EC, switch to the ES* algorithm family instead.
  3. Confirm signing uses the RSAPrivateKey and verification uses the RSAPublicKey from the same pair.
Defensive patterns

Strategy: type-guard

When it happens

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

Appendix: source

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

                ECKey ecKey = (ECKey) key;
                int size = ecKey.getParams().getOrder().bitLength();
                if (size < this.minKeyLength) {
                    String msg = "The " + keyType(signing) + " key's size (ECParameterSpec order) is " + size +
                            " bits which is not secure enough for the " + name() + " algorithm.  The JWT " +
                            "JWA Specification (RFC 7518, Section 3.4) states that keys used with " +
                            name() + " MUST have a size >= " + this.minKeyLength +
                            " bits.  Consider using the " + Keys.class.getName() + " class's " +
                            "'keyPairFor(SignatureAlgorithm." + name() + ")' method to create a key pair guaranteed " +
                            "to be secure enough for " + name() + ".  See " +
                            "https://tools.ietf.org/html/rfc7518#section-3.4 for more information.";
                    throw new WeakKeyException(msg);
                }

            } else { //RSA

                if (!(key instanceof RSAKey)) {
                    String msg = familyName + " " + keyType(signing) + " keys must be RSAKey instances.";
                    throw new InvalidKeyException(msg);
                }

                RSAKey rsaKey = (RSAKey) key;
                int size = rsaKey.getModulus().bitLength();
                if (size < this.minKeyLength) {

                    String section = name().startsWith("P") ? "3.5" : "3.3";

                    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 " +
                            section + ") states that keys used with " + name() + " MUST have a size >= " +
                            this.minKeyLength + " bits.  Consider using the " + Keys.class.getName() + " class's " +
                            "'keyPairFor(SignatureAlgorithm." + name() + ")' method to create a key pair guaranteed " +
                            "to be secure enough for " + name() + ".  See " +
                            "https://tools.ietf.org/html/rfc7518#section-" + section + " for more information.";
                    throw new WeakKeyException(msg);
                }
            }

View on GitHub (pinned to fb71496164)