{"record":{"id":"d46b2c789c810d0b","repo":"apereo/cas","slug":"requested-grant-type-is-not-authorized-by-ser-d46b2c","errorCode":null,"errorMessage":"Requested grant type [{}] is not authorized by service definition [{}]","messagePattern":"Requested grant type \\[(.+?)\\] is not authorized by service definition \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-oauth-core-api/src/main/java/org/apereo/cas/support/oauth/validator/token/OAuth20RefreshTokenGrantTypeTokenRequestValidator.java","lineNumber":65,"sourceCode":"        try {\n            refreshToken = configurationContext.getTicketRegistry().getTicket(token, OAuth20RefreshToken.class);\n            LOGGER.trace(\"Found valid refresh token [{}] in the registry\", refreshToken);\n        } catch (final InvalidTicketException e) {\n            LOGGER.warn(\"Provided refresh token [{}] cannot be found in the registry or has expired\", token);\n            return false;\n        }\n\n        LOGGER.debug(\"Received grant type [{}] with client id [{}]\", grantType, clientId);\n        val registeredService = OAuth20Utils.getRegisteredOAuthServiceByClientId(\n            configurationContext.getServicesManager(), clientId);\n        val audit = AuditableContext.builder()\n            .registeredService(registeredService)\n            .build();\n        val accessResult = configurationContext.getRegisteredServiceAccessStrategyEnforcer().execute(audit);\n        accessResult.throwExceptionIfNeeded();\n\n        if (!isGrantTypeSupportedBy(Objects.requireNonNull(registeredService), grantType)) {\n            LOGGER.warn(\"Requested grant type [{}] is not authorized by service definition [{}]\",\n                grantType, Objects.requireNonNull(registeredService).getServiceId());\n            return false;\n        }\n\n        if (refreshToken != null && !Strings.CI.equals(refreshToken.getClientId(), clientId)) {\n            LOGGER.warn(\"Provided refresh token [{}] does not belong to client [{}]\", refreshToken.getId(), clientId);\n            return false;\n        }\n\n        return true;\n    }\n\n    @Override\n    protected OAuth20GrantTypes getGrantType() {\n        return OAuth20GrantTypes.REFRESH_TOKEN;\n    }\n}\n","sourceCodeStart":47,"sourceCodeEnd":83,"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/OAuth20RefreshTokenGrantTypeTokenRequestValidator.java#L47-L83","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before (service JSON)\n\"supportedGrantTypes\": [\"authorization_code\"]\n// after\n\"supportedGrantTypes\": [\"authorization_code\", \"refresh_token\"]","handlingStrategy":"validation","validationCode":"const REFRESH_GRANT = 'urn:ietf:params:oauth:grant-type:refresh_token';\nif (!service.supportedGrantTypes?.includes(REFRESH_GRANT)) {\n  throw new Error('refresh_token grant not authorized for this service definition');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["oauth","grant-type","refresh-token","service-definition"],"backgroundTag":"unsupported-operation","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"}