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

  1. 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
  2. Upgrade CAS to a version supporting the token type you need, or check release notes for added token-exchange support
  3. Log the exact subject_token_type being sent — compare byte-for-byte (trailing slashes/typos matter) with supported constants
  4. 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

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


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)