spring-projects/spring-security · error · OAuth2AuthenticationException

server_error

server_error

Error message

The token generator failed to generate the registration access token.

What it means

This error is thrown by OidcClientRegistrationAuthenticationProvider.registerAccessToken when the configured TokenGenerator returns null instead of an OAuth2Token for the registration access token of a dynamically registered client. It signals a server-side configuration defect: the OAuth2TokenGenerator bean cannot handle the token context (typically an access token with no matching TokenProvider).

Source

Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationProvider.java:334

			.add(OidcClientConfigurationAuthenticationProvider.DEFAULT_CLIENT_CONFIGURATION_AUTHORIZED_SCOPE);
		authorizedScopes = Collections.unmodifiableSet(authorizedScopes);

		// @formatter:off
		OAuth2TokenContext tokenContext = DefaultOAuth2TokenContext.builder()
				.registeredClient(registeredClient)
				.principal(clientPrincipal)
				.authorizationServerContext(AuthorizationServerContextHolder.getContext())
				.authorizedScopes(authorizedScopes)
				.tokenType(OAuth2TokenType.ACCESS_TOKEN)
				.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
				.build();
		// @formatter:on

		OAuth2Token registrationAccessToken = this.tokenGenerator.generate(tokenContext);
		if (registrationAccessToken == null) {
			OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR,
					"The token generator failed to generate the registration access token.", ERROR_URI);
			throw new OAuth2AuthenticationException(error);
		}

		if (this.logger.isTraceEnabled()) {
			this.logger.trace("Generated registration access token");
		}

		// @formatter:off
		OAuth2Authorization.Builder authorizationBuilder = OAuth2Authorization.withRegisteredClient(registeredClient)
				.principalName(registeredClient.getClientId())
				.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
				.authorizedScopes(authorizedScopes);
		// @formatter:on

		OidcAuthenticationProviderUtils.accessToken(authorizationBuilder, registrationAccessToken, tokenContext);

		OAuth2Authorization authorization = authorizationBuilder.build();

		this.authorizationService.save(authorization);

View on GitHub (pinned to 96852e8860)

Solutions

  1. Check the OAuth2TokenGenerator bean wired into OAuth2AuthorizationServerConfigurer/authorizationServer(): ensure it composes a generator able to produce access tokens (e.g. new DelegatingOAuth2TokenGenerator(new JwtGenerator(jwtEncoder), new OAuth2AccessTokenGenerator()))
  2. Verify JwtGenerator is constructed with a functioning JwtEncoder and matching OAuth2TokenCustomizer; a misconfigured encoder causes the generator chain to yield null
  3. Confirm the RegisteredClient's TokenSettings for the registration access token don't select a token format (e.g. reference/reference-only) for which no TokenProvider is registered
  4. Enable trace logging on the provider and step into tokenGenerator.generate to see which generator in the chain accepted/rejected the context

Example fix

// before
@Bean
OAuth2TokenGenerator<?> tokenGenerator() {
    return new OAuth2AccessTokenGenerator(); // cannot satisfy contexts requiring JWTs
}
// after
@Bean
OAuth2TokenGenerator<?> tokenGenerator(JwtEncoder jwtEncoder) {
    JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder);
    return new DelegatingOAuth2TokenGenerator(jwtGenerator, new OAuth2AccessTokenGenerator());
}
Defensive patterns

Strategy: try-catch

Validate before calling

OAuth2TokenGenerator<?> gen = context.getBean(OAuth2TokenGenerator.class);
// sanity check at startup:
OAuth2TokenContext probe = OAuth2TokenContext.builder()
    .registeredClient(client).authorizedScopes(Set.of())
    .tokenType(OAuth2TokenType.ACCESS_TOKEN)
    .authorizationServerContext(AuthorizationServerContextHolder.getContext())
    .build();
if (gen.generate(probe) == null) {
    throw new IllegalStateException("No token generator produces access tokens");
}

Try / catch

try {
    registration = clientRegistrationService.register(registrationRequest);
} catch (OAuth2AuthenticationException e) {
    if (OAuth2ErrorCodes.SERVER_ERROR.equals(e.getError().getErrorCode())) {
        logger.error("Token generator misconfigured: " + e.getError().getDescription(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A client sends a valid OIDC dynamic client registration request (POST /connect/register) and registerAccessToken calls tokenGenerator.generate(tokenContext), which returns null because the authorization server's OAuth2TokenGenerator is unconfigured, set to OAuth2AccessTokenGenerator without the right encoder, or the token settings on the registration request are unsupported.

Common situations: Spring Authorization Server deployments where the OAuth2TokenGenerator bean was customized (e.g. replaced with a JwtGenerator without a JwtEncoder, or an OAuth2AccessTokenGenerator without an OAuth2TokenCustomizer mismatch) or security config upgraded and the default generator chain no longer resolves an access-token generator.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/c41d614bbd9f3385. Report an issue: GitHub.