spring-projects/spring-security · error · OAuth2AuthenticationException
SERVER_ERROR
SERVER_ERROR
Error message
The token generator failed to generate the access token.
What it means
In OAuth2ClientCredentialsAuthenticationProvider.authenticate (the client_credentials grant at the token endpoint), the OAuth2TokenGenerator must produce an access token for the built token context. If generate() returns null — no generator in the chain supports this context — the provider throws this SERVER_ERROR OAuth2AuthenticationException.
Source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientCredentialsAuthenticationProvider.java:147
DefaultOAuth2TokenContext.Builder tokenContextBuilder = DefaultOAuth2TokenContext.builder()
.registeredClient(registeredClient)
.principal(clientPrincipal)
.authorizationServerContext(AuthorizationServerContextHolder.getContext())
.authorizedScopes(authorizedScopes)
.tokenType(OAuth2TokenType.ACCESS_TOKEN)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.authorizationGrant(clientCredentialsAuthentication);
// @formatter:on
if (dPoPProof != null) {
tokenContextBuilder.put(OAuth2TokenContext.DPOP_PROOF_KEY, dPoPProof);
}
OAuth2TokenContext tokenContext = tokenContextBuilder.build();
OAuth2Token generatedAccessToken = this.tokenGenerator.generate(tokenContext);
if (generatedAccessToken == null) {
OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR,
"The token generator failed to generate the access token.", ERROR_URI);
throw new OAuth2AuthenticationException(error);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Generated access token");
}
// @formatter:off
OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient)
.principalName(clientPrincipal.getName())
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.authorizedScopes(authorizedScopes);
// @formatter:on
OAuth2AccessToken accessToken = OAuth2AuthenticationProviderUtils.accessToken(authorizationBuilder,
generatedAccessToken, tokenContext);
OAuth2Authorization authorization = authorizationBuilder.build();
View on GitHub (pinned to 96852e8860)
Solutions
- Use the composite token generator (e.g. DelegatingOAuth2TokenGenerator(JwtGenerator, OAuth2AccessTokenGenerator, OAuth2RefreshTokenGenerator)) built by OAuth2ConfigurerUtils.
- If a custom generator is used, make it return a non-null token for ACCESS_TOKEN contexts or delegate to the next generator.
- Verify the NimbusJwtEncoder and JWKSource beans are correctly configured so JwtGenerator can encode tokens.
- Check the RegisteredClient token settings to ensure the requested access-token format matches an available generator.
Example fix
// before
@Bean
OAuth2TokenGenerator<?> tokenGenerator() {
return new OAuth2AccessTokenGenerator(); // no JWT support; fails JWT contexts
}
// after
@Bean
OAuth2TokenGenerator<?> tokenGenerator(JWKSource<SecurityContext> jwkSource) {
JwtGenerator jwtGenerator = new JwtGenerator(new NimbusJwtEncoder(jwkSource));
return new DelegatingOAuth2TokenGenerator(jwtGenerator, new OAuth2AccessTokenGenerator());
} Defensive patterns
Strategy: try-catch
Validate before calling
OAuth2Token t = tokenGenerator.generate(clientCredentialsAccessTokenContext);
if (t == null) {
throw new IllegalStateException("Token generator must handle ACCESS_TOKEN contexts for client_credentials");
} Try / catch
try {
// POST /oauth2/token grant_type=client_credentials
} catch (OAuth2AuthenticationException ex) {
if (OAuth2ErrorCodes.SERVER_ERROR.equals(ex.getError().getErrorCode())
&& ex.getError().getDescription().contains("access token")) {
log.error("client_credentials failed: no generator produced an access token; check JwtGenerator wiring");
}
throw ex;
} Prevention
- Use the standard composite token generator (JwtGenerator + OAuth2AccessTokenGenerator)
- Keep NimbusJwtEncoder/JWKSource beans intact when customizing authorization server config
- Add a client_credentials integration test to your CI pipeline for the authorization server
When it happens
Trigger: A client calls the token endpoint with grant_type=client_credentials while the authorization server's OAuth2TokenGenerator returns null for the ACCESS_TOKEN context (e.g. a custom generator without an encoder, or wrong token settings for JWT/reference format).
Common situations: Replacing the default token generator bean with a narrow custom one; JwtEncoder/JWKSource misconfiguration so JwtGenerator effectively fails or is excluded; token settings (access token TTL/format) not matching available generators.
Related errors
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/1549ba004f66ccd7.
Report an issue: GitHub.