spring-projects/spring-security · error · OAuth2AuthenticationException

server_error

server_error

Error message

The token generator failed to generate the device code.

What it means

During the OAuth 2.0 Device Authorization Grant flow, the provider asks the configured deviceCodeGenerator (OAuth2TokenGenerator) for an OAuth2DeviceCode. If the generator returns null — meaning no generator in the composed chain supports the DEVICE_CODE token type — the server cannot proceed and throws a server_error OAuth2AuthenticationException.

Source

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

			this.logger.trace("Validated device authorization request parameters");
		}

		// @formatter:off
		DefaultOAuth2TokenContext.Builder tokenContextBuilder = DefaultOAuth2TokenContext.builder()
				.registeredClient(registeredClient)
				.principal(clientPrincipal)
				.authorizationServerContext(AuthorizationServerContextHolder.getContext())
				.authorizationGrantType(AuthorizationGrantType.DEVICE_CODE)
				.authorizationGrant(deviceAuthorizationRequestAuthentication);
		// @formatter:on

		// Generate a high-entropy string to use as the device code
		OAuth2TokenContext tokenContext = tokenContextBuilder.tokenType(DEVICE_CODE_TOKEN_TYPE).build();
		OAuth2DeviceCode deviceCode = this.deviceCodeGenerator.generate(tokenContext);
		if (deviceCode == null) {
			OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR,
					"The token generator failed to generate the device code.", ERROR_URI);
			throw new OAuth2AuthenticationException(error);
		}

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

		// Generate a low-entropy string to use as the user code
		tokenContext = tokenContextBuilder.tokenType(USER_CODE_TOKEN_TYPE).build();
		OAuth2UserCode userCode = this.userCodeGenerator.generate(tokenContext);
		if (userCode == null) {
			OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR,
					"The token generator failed to generate the user code.", ERROR_URI);
			throw new OAuth2AuthenticationException(error);
		}

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

View on GitHub (pinned to 96852e8860)

Solutions

  1. Ensure the authorization server's OAuth2TokenGenerator includes a generator supporting OAuth2DeviceCode (e.g. keep the default composite or add OAuth2DeviceCodeGenerator via OAuth2AuthorizationServerConfigurer).
  2. If using a custom tokenGenerator(), delegate to a generator that handles DEVICE_CODE_TOKEN_TYPE, or return a non-null device code for that context.
  3. Inspect your custom generator's generate(): it must not return null for tokenType OAuth2ParameterNames.DEVICE_CODE contexts; throw or generate instead.
  4. Catch OAuth2AuthenticationException and surface error=server_error to the device client so it can retry.

Example fix

// before
http.oauth2AuthorizationServer((authorizationServer) -> authorizationServer
    .tokenGenerator(new JwtGenerator(jwkSourceEncoder)));
// after
http.oauth2AuthorizationServer((authorizationServer) -> authorizationServer
    .tokenGenerator(new DelegatingOAuth2TokenGenerator(
        new JwtGenerator(jwkSourceEncoder),
        new OAuth2AccessTokenGenerator(),
        new OAuth2RefreshTokenGenerator())));
Defensive patterns

Strategy: try-catch

Validate before calling

OAuth2TokenGenerator<?> gen = authorizationServerSettingsCustomizer.getTokenGenerator();
if (gen == null || !supportsDeviceCode(gen)) {
    throw new IllegalStateException("No OAuth2TokenGenerator configured for device codes");
}

Try / catch

try {
    return deviceAuthorizationEndpoint.process(request);
} catch (OAuth2AuthenticationException e) {
    if (OAuth2ErrorCodes.SERVER_ERROR.equals(e.getError().getErrorCode())) {
        // generator misconfiguration; surface to operators
        throw new IllegalStateException("Token generator returned no device code", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling OAuth2DeviceAuthorizationRequestAuthenticationProvider.authenticate() when the DeviceClientAuthenticationProvider/authorization server settings have no OAuth2TokenGenerator able to produce an OAuth2DeviceCode for tokenType DEVICE_CODE_TOKEN_TYPE (generator chain returns null).

Common situations: Customizing OAuth2Configurer tokenGenerator()/authorizationServerSettings and replacing the default composite generator without a device-code-capable generator; a custom generator that returns null for unrecognized contexts; narrowing the generator set so OAuth2DeviceCodeGenerator is excluded.

Related errors


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