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 OAuth2AuthorizationCodeAuthenticationProvider.authenticate, after validating the authorization code grant, the configured OAuth2TokenGenerator is asked to produce an access token for the token context. If generate() returns null — meaning no generator in the composite 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/OAuth2AuthorizationCodeAuthenticationProvider.java:224
.authorizationServerContext(AuthorizationServerContextHolder.getContext())
.authorization(authorization)
.authorizedScopes(authorization.getAuthorizedScopes())
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrant(authorizationCodeAuthentication);
// @formatter:on
if (dPoPProof != null) {
tokenContextBuilder.put(OAuth2TokenContext.DPOP_PROOF_KEY, dPoPProof);
}
OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.from(authorization);
// ----- Access token -----
OAuth2TokenContext tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.ACCESS_TOKEN).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");
}
OAuth2AccessToken accessToken = OAuth2AuthenticationProviderUtils.accessToken(authorizationBuilder,
generatedAccessToken, tokenContext);
// ----- Refresh token -----
OAuth2RefreshToken refreshToken = null;
// Do not issue refresh token to public client
if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN)) {
tokenContext = tokenContextBuilder.tokenType(OAuth2TokenType.REFRESH_TOKEN).build();
OAuth2Token generatedRefreshToken = this.tokenGenerator.generate(tokenContext);
if (generatedRefreshToken != null) {
if (!(generatedRefreshToken instanceof OAuth2RefreshToken)) {
OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR,View on GitHub (pinned to 96852e8860)
Solutions
- Use OAuth2AccessTokenGenerator or the composite created by OAuth2ConfigurerUtils.getTokenGenerator(...) so the generator chain covers the context.
- If using a custom OAuth2TokenGenerator, ensure its generate(context) returns a non-null token for ACCESS_TOKEN contexts or delegates to a next generator.
- Check that token settings (access-token format JWT vs reference) match the generators registered.
- Revert to the default DSL configuration if you recently customized token generation.
Example fix
// before
@Bean
OAuth2TokenGenerator<?> tokenGenerator() {
return new MyNarrowGenerator(); // returns null for 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
// At startup, smoke-test the generator
OAuth2Token t = tokenGenerator.generate(new OAuth2TokenContext() {});
assert t != null : "OAuth2TokenGenerator must produce tokens for access token contexts"; Try / catch
try {
// call /oauth2/token with authorization_code grant
} catch (OAuth2AuthenticationException ex) {
if (OAuth2ErrorCodes.SERVER_ERROR.equals(ex.getError().getErrorCode())
&& ex.getError().getDescription().contains("access token")) {
log.error("Token generator misconfigured: no generator produced an access token");
}
throw ex;
} Prevention
- Keep the default OAuth2TokenGenerator from OAuth2ConfigurerUtils unless you must customize
- If customizing, use DelegatingOAuth2TokenGenerator with JwtGenerator + OAuth2AccessTokenGenerator
- Add a boot-time integration test exercising the full authorization_code token issuance
When it happens
Trigger: Calling the token endpoint with an authorization_code grant while the authorization server's OAuth2TokenGenerator bean produces no access token for the context (e.g. a custom generator that returns null, or a generator configured without any matching encoder).
Common situations: Overriding the default token generator bean with a partial one; registering only a JwtGenerator without matching settings, or only an OAuth2AccessTokenGenerator while JWT format is required; misconfigured HttpMessageConverter/encoder beans after customization.
Related errors
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/c00dd3e5f79a7256.
Report an issue: GitHub.