apereo/cas · error · IllegalArgumentException

Unsupported key type:

Error message

Unsupported key type: 

What it means

The signed client JWKS registration request JWT must be signed with a supported key type. The controller matches the embedded JWK with a pattern switch supporting EC, RSA, and Octet Key Pair (Ed25519) keys; any other key type (e.g. 'oct' symmetric keys) causes an IllegalArgumentException naming the key type.

Solutions

  1. Sign the registration JWT with an RSA, EC (P-256 etc.), or Ed25519 (OctetKeyPair) key and embed that JWK in the JWS header
  2. Replace any symmetric 'oct' key with an asymmetric keypair
  3. Regenerate the client key with a supported algorithm and retry the registration

Example fix

// before: HMAC-signed JWS with oct key in header
JWSSigner signer = new MACSigner(sharedSecret);
// after: RSA-signed JWS with RSAKey in header
RSAKey rsaJwk = new RSAKeyGenerator(2048).generate();
JWSSigner signer = new RSASSASigner(rsaJwk);
Defensive patterns

Strategy: validation

Validate before calling

JWK jwk = parsedJws.getHeader().getJWK();
if (!(jwk instanceof ECKey) && !(jwk instanceof RSAKey) && !(jwk instanceof OctetKeyPair)) {
    throw new IllegalArgumentException("key type not supported: " + jwk.getKeyType());
}

Type guard

boolean supported = jwk instanceof ECKey || jwk instanceof RSAKey || jwk instanceof OctetKeyPair;

Try / catch

try { controller.handleRegistration(request, response); }
catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Unsupported key type")) { /* re-sign JWT with RSA/EC/Ed25519 key */ }
    else throw e;
}

Prevention

When it happens

Trigger: handleRegistration(): the JWS header's embedded JWK is not an ECKey, RSAKey, or OctetKeyPair — e.g. a symmetric 'oct' key or an unsupported curve/algorithm — so the switch falls to the default branch.

Common situations: Signing the registration JWT with an HMAC/shared secret ('oct' key) instead of an asymmetric key; generating the JWK with an unsupported OKP curve other than Ed25519; client library defaulting to a key type CAS does not accept.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/5ae63e30ca08e528. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/web/controllers/jwks/OidcJwksRegistrationEndpointController.java:111

        val audit = AuditableContext.builder()
            .registeredService(registeredService)
            .authentication(accessTokenTicket.getAuthentication())
            .build();
        val accessResult = configurationContext.getRegisteredServiceAccessStrategyEnforcer().execute(audit);
        accessResult.throwExceptionIfNeeded();
        
        val jws = JWSObject.parse(registrationRequest.proof());

        val alg = jws.getHeader().getAlgorithm();
        FunctionUtils.throwIf(!JWSAlgorithm.Family.EC.contains(alg) && !JWSAlgorithm.Family.RSA.contains(alg) && !JWSAlgorithm.EdDSA.equals(alg),
            () -> new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid algorithm: " + alg));

        val jwk = jws.getHeader().getJWK();
        val verifier = switch (jwk) {
            case ECKey ecKey -> new ECDSAVerifier(ecKey);
            case RSAKey rsaKey -> new RSASSAVerifier(rsaKey);
            case OctetKeyPair okp -> new Ed25519Verifier(okp.toPublicJWK());
            default -> throw new IllegalArgumentException("Unsupported key type: " + jwk.getKeyType());
        };
        if (!jws.verify((JWSVerifier) verifier)) {
            throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid signature");
        }
        val jkt = jwk.computeThumbprint().toString();
        clientJwksRegistrationStore.save(accessTokenTicket.getClientId(), jkt, jwk.toPublicJWK().toJSONString());
        return ResponseEntity.ok(new ClientJwksRegistrationResponse(jkt));
    }

    /**
     * Handle errors.
     *
     * @param ex the ex
     * @return the response entity
     */
    @ExceptionHandler(Exception.class)
    @SuppressWarnings("UnusedMethod")
    private static ResponseEntity<String> handle(final Exception ex) {

View on GitHub (pinned to e7288fc434)