{"record":{"id":"83e463d602a9e1c7","repo":"apereo/cas","slug":"subject-token-type-s-is-not-supported","errorCode":null,"errorMessage":"Subject token type %s is not supported","messagePattern":"Subject token type (.+?) is not supported","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-oauth-core-api/src/main/java/org/apereo/cas/support/oauth/validator/token/OAuth20TokenExchangeGrantTypeTokenRequestValidator.java","lineNumber":92,"sourceCode":"        return tokenExchangePolicy == null || tokenExchangePolicy.isTokenExchangeAllowed(registeredService, resources, audience, requestedTokenType);\n    }\n\n    protected @Nullable OAuthRegisteredService extractRegisteredService(final String subjectTokenType,\n                                                                        final String subjectToken) throws Exception {\n        val configurationContext = getConfigurationContext().getObject();\n        return switch (OAuth20TokenExchangeTypes.from(subjectTokenType)) {\n            case ACCESS_TOKEN -> {\n                val accessToken = configurationContext.getTicketRegistry().getTicket(subjectToken, OAuth20AccessToken.class);\n                yield OAuth20Utils.getRegisteredOAuthServiceByClientId(configurationContext.getServicesManager(), accessToken.getClientId());\n            }\n            case JWT -> {\n                val claimSet = configurationContext.getAccessTokenJwtBuilder().unpack(Optional.empty(), subjectToken);\n                jwtClaimsSetVerifier.verify(claimSet, new SimpleSecurityContext());\n                val service = Objects.requireNonNull(configurationContext.getWebApplicationServiceServiceFactory().createService(claimSet.getIssuer()));\n                service.getAttributes().put(OAuth20Constants.CLIENT_ID, List.of(claimSet.getSubject()));\n                yield OAuth20Utils.getRegisteredOAuthServiceByClientId(configurationContext.getServicesManager(), claimSet.getSubject());\n            }\n            default -> throw new IllegalArgumentException(\"Subject token type %s is not supported\".formatted(subjectTokenType));\n        };\n    }\n\n    @Override\n    protected OAuth20GrantTypes getGrantType() {\n        return OAuth20GrantTypes.TOKEN_EXCHANGE;\n    }\n}\n","sourceCodeStart":74,"sourceCodeEnd":101,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-oauth-core-api/src/main/java/org/apereo/cas/support/oauth/validator/token/OAuth20TokenExchangeGrantTypeTokenRequestValidator.java#L74-L101","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":"// before\nsubject_token_type=urn:ietf:params:oauth:token-type:jwt\n// after\nsubject_token_type=urn:ietf:params:oauth:token-type:access_token","handlingStrategy":"validation","validationCode":"const SUPPORTED = ['urn:ietf:params:oauth:token-type:access_token','urn:ietf:params:oauth:token-type:jwt'];\nif (!SUPPORTED.includes(subjectTokenType)) throw new Error(`subject_token_type ${subjectTokenType} is not supported by this CAS version`);","typeGuard":null,"tryCatchPattern":"try {\n  await tokenExchange({ subjectTokenType });\n} catch (e) {\n  if (String(e.message).includes('is not supported')) {\n    // switch to a supported subject_token_type or upgrade CAS\n  }\n}","preventionTips":["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"],"tags":["oauth2","token-exchange","unsupported"],"backgroundTag":"unsupported-enum-value","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}