spring-projects/spring-security · error · OAuth2AuthorizationCodeRequestAuthenticationException

SERVER_ERROR

SERVER_ERROR

Error message

The token generator failed to generate the authorization code.

What it means

In OAuth2AuthorizationConsentAuthenticationProvider.authenticate (the consent approval step of the authorization code flow), after recording consent the provider generates a new authorization code via the OAuth2AuthorizationCodeGenerator. If generation yields null, it throws OAuth2AuthorizationCodeRequestAuthenticationException with this SERVER_ERROR message, aborting the redirect back to the client.

Source

Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationConsentAuthenticationProvider.java:242

			throw createException(OAuth2ErrorCodes.ACCESS_DENIED, OAuth2ParameterNames.CLIENT_ID,
					authorizationConsentAuthentication, registeredClient, authorizationRequest);
		}

		OAuth2AuthorizationConsent authorizationConsent = authorizationConsentBuilder.build();
		if (currentAuthorizationConsent == null || !authorizationConsent.equals(currentAuthorizationConsent)) {
			this.authorizationConsentService.save(authorizationConsent);
			if (this.logger.isTraceEnabled()) {
				this.logger.trace("Saved authorization consent");
			}
		}

		OAuth2TokenContext tokenContext = createAuthorizationCodeTokenContext(authorizationConsentAuthentication,
				registeredClient, authorization, authorizedScopes);
		OAuth2AuthorizationCode authorizationCode = this.authorizationCodeGenerator.generate(tokenContext);
		if (authorizationCode == null) {
			OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR,
					"The token generator failed to generate the authorization code.", ERROR_URI);
			throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);
		}

		if (this.logger.isTraceEnabled()) {
			this.logger.trace("Generated authorization code");
		}

		OAuth2Authorization updatedAuthorization = OAuth2Authorization.from(authorization)
			.authorizedScopes(authorizedScopes)
			.token(authorizationCode)
			.attributes((attrs) -> attrs.remove(OAuth2ParameterNames.STATE))
			.build();
		this.authorizationService.save(updatedAuthorization);

		if (this.logger.isTraceEnabled()) {
			this.logger.trace("Saved authorization");
		}

		String redirectUri = authorizationRequest.getRedirectUri();

View on GitHub (pinned to 96852e8860)

Solutions

  1. Register the default OAuth2AuthorizationCodeGenerator or include it in your generator chain.
  2. Fix any custom OAuth2AuthorizationCodeGenerator so it returns a non-null OAuth2AuthorizationCode for consent-derived contexts.
  3. Verify createAuthorizationCodeTokenContext inputs (authorization, scopes) are populated so the generator recognizes the context.
  4. Revert recent authorization server config customizations to the defaults and re-apply incrementally.

Example fix

// before
class MyCodeGenerator implements OAuth2TokenGenerator<OAuth2AuthorizationCode> {
    public OAuth2AuthorizationCode generate(OAuth2TokenContext ctx) { return null; }
}

// after
class MyCodeGenerator implements OAuth2TokenGenerator<OAuth2AuthorizationCode> {
    public OAuth2AuthorizationCode generate(OAuth2TokenContext ctx) {
        return new OAuth2AuthorizationCode(Base64.getUrlEncoder().withoutPadding()
            .encodeToString(SecureRandom.getInstanceStrong().generateSeed(32)),
            Instant.now().plus(5, ChronoUnit.MINUTES));
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

OAuth2AuthorizationCode code = authorizationCodeGenerator.generate(consentCodeContext);
if (code == null) {
    throw new IllegalStateException("Consent flow cannot mint authorization code; check generator bean");
}

Try / catch

try {
    // POST /oauth2/authorize (consent approval)
} catch (OAuth2AuthorizationCodeRequestAuthenticationException ex) {
    if (OAuth2ErrorCodes.SERVER_ERROR.equals(ex.getError().getErrorCode())) {
        log.error("Consent approved but code generation failed: {}", ex.getError().getDescription());
    }
    throw ex;
}

Prevention

When it happens

Trigger: The user approves consent (POST to /oauth2/authorize) and the provider must mint a fresh authorization code, but the authorization code generator bean is absent, misconfigured, or a custom implementation returns null for the context.

Common situations: Same as the authorization-request variant: custom generator returning null, removed default generator bean, or broken delegation in a composite generator when customizing the authorization server.

Related errors


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