apereo/cas · error · IllegalArgumentException
Subject token type is not supported
Error message
Subject token type %s is not supported
What it means
Thrown as IllegalArgumentException while extracting the registered service for a token-exchange grant request when the requested subject_token_type is not one of the supported types (e.g. access token vs JWT identity token). The switch statement has no case for the given token type identifier and falls to the default branch.
Solutions
- Send a supported subject_token_type value (the ones handled by the validator's switch: access-token and JWT identity-token cases) and verify the exact URI string against RFC 8693 constants
- Upgrade CAS to a version supporting the token type you need, or check release notes for added token-exchange support
- Log the exact subject_token_type being sent — compare byte-for-byte (trailing slashes/typos matter) with supported constants
- If you need an unsupported token type, contribute/implement an additional case in the validator
Example fix
// before subject_token_type=urn:ietf:params:oauth:token-type:jwt // after subject_token_type=urn:ietf:params:oauth:token-type:access_token
Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = ['urn:ietf:params:oauth:token-type:access_token','urn:ietf:params:oauth:token-type:jwt'];
if (!SUPPORTED.includes(subjectTokenType)) throw new Error(`subject_token_type ${subjectTokenType} is not supported by this CAS version`); Try / catch
try {
await tokenExchange({ subjectTokenType });
} catch (e) {
if (String(e.message).includes('is not supported')) {
// switch to a supported subject_token_type or upgrade CAS
}
} Prevention
- Copy RFC 8693 token-type URIs exactly (watch underscores vs hyphens)
- Confirm which token types your CAS build's token-exchange validator implements
- Pin client and server versions to keep supported types aligned
When it happens
Trigger: POSTing grant_type=token_exchange with a subject_token_type URI that the validator's switch does not recognize — an unsupported/typo'd URN or URL such as an unexpected RFC 8693 token-type identifier.
Common situations: Client uses an RFC 8693 token-type constant not implemented by this CAS version; typo or wrong casing in the subject_token_type URI; newer client library emitting token types older CAS builds do not know; sending id_token where only access-token/JWT cases are handled (or vice versa).
Related errors
- Failed to acquire access token
- Invalid client credentials provided for registered service:
- Code verification method is unrecognized:
- Client Credentials provided is not valid for service:
- Invalid token:
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/83e463d602a9e1c7.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-oauth-core-api/src/main/java/org/apereo/cas/support/oauth/validator/token/OAuth20TokenExchangeGrantTypeTokenRequestValidator.java:92
return tokenExchangePolicy == null || tokenExchangePolicy.isTokenExchangeAllowed(registeredService, resources, audience, requestedTokenType);
}
protected @Nullable OAuthRegisteredService extractRegisteredService(final String subjectTokenType,
final String subjectToken) throws Exception {
val configurationContext = getConfigurationContext().getObject();
return switch (OAuth20TokenExchangeTypes.from(subjectTokenType)) {
case ACCESS_TOKEN -> {
val accessToken = configurationContext.getTicketRegistry().getTicket(subjectToken, OAuth20AccessToken.class);
yield OAuth20Utils.getRegisteredOAuthServiceByClientId(configurationContext.getServicesManager(), accessToken.getClientId());
}
case JWT -> {
val claimSet = configurationContext.getAccessTokenJwtBuilder().unpack(Optional.empty(), subjectToken);
jwtClaimsSetVerifier.verify(claimSet, new SimpleSecurityContext());
val service = Objects.requireNonNull(configurationContext.getWebApplicationServiceServiceFactory().createService(claimSet.getIssuer()));
service.getAttributes().put(OAuth20Constants.CLIENT_ID, List.of(claimSet.getSubject()));
yield OAuth20Utils.getRegisteredOAuthServiceByClientId(configurationContext.getServicesManager(), claimSet.getSubject());
}
default -> throw new IllegalArgumentException("Subject token type %s is not supported".formatted(subjectTokenType));
};
}
@Override
protected OAuth20GrantTypes getGrantType() {
return OAuth20GrantTypes.TOKEN_EXCHANGE;
}
}
View on GitHub (pinned to e7288fc434)