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
- Sign the registration JWT with an RSA, EC (P-256 etc.), or Ed25519 (OctetKeyPair) key and embed that JWK in the JWS header
- Replace any symmetric 'oct' key with an asymmetric keypair
- 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
- Use RSA, EC, or Ed25519 keys for client JWKS registration JWTs
- Never use symmetric 'oct' keys for this endpoint
- Check the generated JWK's kty before embedding it in the JWS header
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
- Invalid signature
- JWKS cannot contain expressions
- Service with client id is configured to encrypt tokens, yet…
- Invalid access token
- Unable to locate JSON web key for
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)