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

  1. Use the composite token generator (e.g. DelegatingOAuth2TokenGenerator(JwtGenerator, OAuth2AccessTokenGenerator, OAuth2RefreshTokenGenerator)) built by OAuth2ConfigurerUtils.
  2. If a custom generator is used, make it return a non-null token for ACCESS_TOKEN contexts or delegate to the next generator.
  3. Verify the NimbusJwtEncoder and JWKSource beans are correctly configured so JwtGenerator can encode tokens.
  4. 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

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.