apereo/cas · warning
Requested grant type
Error message
Requested grant type [{}] is not authorized by service definition [{}] What it means
After confirming the refresh token exists, OAuth20RefreshTokenGrantTypeTokenRequestValidator checks that the registered service authorizes the refresh-token grant type via isGrantTypeSupportedBy. If the service definition's supported grant types do not include the refresh_token grant, the validator warns and returns false, denying the token refresh.
Solutions
- Add "urn:ietf:params:oauth:grant-type:refresh_token" to the service's supportedGrantTypes.
- Reload/redeploy the service registry so ServicesManager sees the update.
- Audit all clients that perform token refresh to ensure their service definitions list the grant type.
- Verify no service-matching ambiguity causes a different (wrong) service definition to be selected for this clientId.
Example fix
// before (service JSON) "supportedGrantTypes": ["authorization_code"] // after "supportedGrantTypes": ["authorization_code", "refresh_token"]
Defensive patterns
Strategy: validation
Validate before calling
const REFRESH_GRANT = 'urn:ietf:params:oauth:grant-type:refresh_token';
if (!service.supportedGrantTypes?.includes(REFRESH_GRANT)) {
throw new Error('refresh_token grant not authorized for this service definition');
} Prevention
- Add refresh_token to supportedGrantTypes for every client that refreshes tokens
- Validate service JSON with a schema/lint before deploying
- Re-run refresh-flow tests after registry changes
When it happens
Trigger: A grant_type=refresh_token request whose clientId resolves to a service with an empty or non-matching supportedGrantTypes list (missing urn:ietf:params:oauth:grant-type:refresh_token).
Common situations: Service definition authored with only authorization_code in supportedGrantTypes; registry entry edited without reloading; deployment upgraded to a CAS version that enforces grant-type authorization strictly.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Requested grant type
- Response type [ ] or grant type [ ] is not supported.
- Provided refresh token
- Provided refresh token
- Requested grant type
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/d46b2c789c810d0b.
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/OAuth20RefreshTokenGrantTypeTokenRequestValidator.java:65
try {
refreshToken = configurationContext.getTicketRegistry().getTicket(token, OAuth20RefreshToken.class);
LOGGER.trace("Found valid refresh token [{}] in the registry", refreshToken);
} catch (final InvalidTicketException e) {
LOGGER.warn("Provided refresh token [{}] cannot be found in the registry or has expired", token);
return false;
}
LOGGER.debug("Received grant type [{}] with client id [{}]", grantType, clientId);
val registeredService = OAuth20Utils.getRegisteredOAuthServiceByClientId(
configurationContext.getServicesManager(), clientId);
val audit = AuditableContext.builder()
.registeredService(registeredService)
.build();
val accessResult = configurationContext.getRegisteredServiceAccessStrategyEnforcer().execute(audit);
accessResult.throwExceptionIfNeeded();
if (!isGrantTypeSupportedBy(Objects.requireNonNull(registeredService), grantType)) {
LOGGER.warn("Requested grant type [{}] is not authorized by service definition [{}]",
grantType, Objects.requireNonNull(registeredService).getServiceId());
return false;
}
if (refreshToken != null && !Strings.CI.equals(refreshToken.getClientId(), clientId)) {
LOGGER.warn("Provided refresh token [{}] does not belong to client [{}]", refreshToken.getId(), clientId);
return false;
}
return true;
}
@Override
protected OAuth20GrantTypes getGrantType() {
return OAuth20GrantTypes.REFRESH_TOKEN;
}
}
View on GitHub (pinned to e7288fc434)