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
- 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()))
- Verify JwtGenerator is constructed with a functioning JwtEncoder and matching OAuth2TokenCustomizer; a misconfigured encoder causes the generator chain to yield null
- 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
- 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
- Compose the token generator with DelegatingOAuth2TokenGenerator covering both JWT and opaque access tokens
- Add a startup smoke test that generates a token for a sample context
- Keep JwtGenerator's JwtEncoder bean validated in integration tests
- After Spring Authorization Server upgrades, re-verify the OAuth2TokenGenerator bean composition
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
- Invalid Client Registration: + fieldName
- Invalid Client Registration: + fieldName
- invalid_client_metadata
- invalid_scope
- invalid_scope
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/c41d614bbd9f3385.
Report an issue: GitHub.