{"record":{"id":"09efed2987e60de0","repo":"spring-projects/spring-security","slug":"unsupported-grant-type","errorCode":"unsupported_grant_type","errorMessage":"OAuth 2.0 Parameter: grant_type","messagePattern":"OAuth 2\\.0 Parameter: grant_type","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":400,"severity":"error","filePath":"oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2TokenEndpointFilter.java","lineNumber":163,"sourceCode":"\n\t@Override\n\tprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)\n\t\t\tthrows ServletException, IOException {\n\n\t\tif (!this.tokenEndpointMatcher.matches(request)) {\n\t\t\tfilterChain.doFilter(request, response);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tString[] grantTypes = request.getParameterValues(OAuth2ParameterNames.GRANT_TYPE);\n\t\t\tif (grantTypes == null || grantTypes.length != 1) {\n\t\t\t\tthrow createException(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.GRANT_TYPE);\n\t\t\t}\n\n\t\t\tAuthentication authorizationGrantAuthentication = this.authenticationConverter.convert(request);\n\t\t\tif (authorizationGrantAuthentication == null) {\n\t\t\t\tthrow createException(OAuth2ErrorCodes.UNSUPPORTED_GRANT_TYPE, OAuth2ParameterNames.GRANT_TYPE);\n\t\t\t}\n\t\t\tif (authorizationGrantAuthentication instanceof AbstractAuthenticationToken authenticationToken) {\n\t\t\t\tauthenticationToken.setDetails(this.authenticationDetailsSource.buildDetails(request));\n\t\t\t}\n\n\t\t\tOAuth2AccessTokenAuthenticationToken accessTokenAuthentication = (OAuth2AccessTokenAuthenticationToken) this.authenticationManager\n\t\t\t\t.authenticate(authorizationGrantAuthentication);\n\t\t\tthis.authenticationSuccessHandler.onAuthenticationSuccess(request, response, accessTokenAuthentication);\n\t\t}\n\t\tcatch (OAuth2AuthenticationException ex) {\n\t\t\tSecurityContextHolder.clearContext();\n\t\t\tif (this.logger.isTraceEnabled()) {\n\t\t\t\tthis.logger.trace(LogMessage.format(\"Token request failed: %s\", ex.getError()), ex);\n\t\t\t}\n\t\t\tthis.authenticationFailureHandler.onAuthenticationFailure(request, response, ex);\n\t\t}\n\t}\n","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2TokenEndpointFilter.java#L145-L181","documentation":"After grant_type passes the single-value check, OAuth2TokenEndpointFilter asks the configured AuthenticationConverter to build a grant authentication. If no converter recognizes the grant_type, the filter throws an OAuth2AuthenticationException with error code 'unsupported_grant_type', which maps to an HTTP 400 'unsupported_grant_type' response as defined by OAuth 2.0.","triggerScenarios":"Requesting the token endpoint with a grant_type not enabled on the authorization server, e.g. 'password', 'client_credentials' when disabled, 'urn:ietf:params:oauth:grant-type:token-exchange' without the corresponding dependency/converter, or a typo like 'authorizationCode'.","commonSituations":"Authorization server not configured with the grant (e.g. missing OAuth2TokenExchangeAuthenticationProvider/converter), Spring Security version where a grant type is not yet supported, or client requesting a grant the server intentionally restricts.","solutions":["Enable/registers support for the requested grant type (e.g. add OAuth2ClientCredentialsAuthenticationProvider or the token-exchange dependencies) in the authorization server security config","Correct the grant_type spelling on the client (e.g. authorization_code, refresh_token, client_credentials)","Check the Spring Security OAuth2 Authorization Server version supports the requested grant"],"exampleFix":"// before: server only allows authorization_code\nhttp.oauth2AuthorizationServer(authorizationServer -> authorizationServer.tokenEndpoint(t -> t.accessTokenRequestConverter(new OAuth2AuthorizationCodeAuthenticationConverter(...))))\n// after: also support client_credentials\nhttp.oauth2AuthorizationServer(authorizationServer -> authorizationServer\n    .tokenEndpoint(t -> t.accessTokenRequestConverters(c -> c.add(new OAuth2ClientCredentialsAuthenticationConverter()))))","handlingStrategy":"try-catch","validationCode":"Set<String> supported = Set.of(\"authorization_code\",\"refresh_token\",\"client_credentials\",\"urn:ietf:params:oauth:grant-type:device_code\");\nif (!supported.contains(grantType)) {\n    throw new IllegalArgumentException(\"grant_type not enabled on this server: \" + grantType);\n}","typeGuard":null,"tryCatchPattern":"try {\n    TokenResponse r = client.tokenRequest(...);\n} catch (OAuth2ErrorResponseException ex) {\n    if (\"unsupported_grant_type\".equals(ex.getError().getErrorCode())) {\n        // fall back to a supported grant or surface a config error\n    }\n}","preventionTips":["Keep server grant configuration and client grant usage in sync","After adding a grant type, confirm the matching converter/provider is registered","Test the token endpoint after Spring Security version upgrades"],"tags":["oauth2","token-endpoint","grant-type","unsupported"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}