spring-projects/spring-security · error · OAuth2AuthenticationException

OAuth 2.0 Parameter: + parameterName

Error message

OAuth 2.0 Parameter: + parameterName

What it means

Helper throwError() builds an OAuth2Error whose description is 'OAuth 2.0 Parameter: <parameterName>' and throws it as an OAuth2AuthenticationException. It is the provider's generic way of rejecting device authorization requests with missing/invalid request parameters (e.g. missing client_id or scope per RFC 8628).

Source

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

	 */
	public void setDeviceCodeGenerator(OAuth2TokenGenerator<OAuth2DeviceCode> deviceCodeGenerator) {
		Assert.notNull(deviceCodeGenerator, "deviceCodeGenerator cannot be null");
		this.deviceCodeGenerator = deviceCodeGenerator;
	}

	/**
	 * Sets the {@link OAuth2TokenGenerator} that generates the {@link OAuth2UserCode}.
	 * @param userCodeGenerator the {@link OAuth2TokenGenerator} that generates the
	 * {@link OAuth2UserCode}
	 */
	public void setUserCodeGenerator(OAuth2TokenGenerator<OAuth2UserCode> userCodeGenerator) {
		Assert.notNull(userCodeGenerator, "userCodeGenerator cannot be null");
		this.userCodeGenerator = userCodeGenerator;
	}

	private static void throwError(String errorCode, String parameterName) {
		OAuth2Error error = new OAuth2Error(errorCode, "OAuth 2.0 Parameter: " + parameterName, ERROR_URI);
		throw new OAuth2AuthenticationException(error);
	}

	private static final class OAuth2DeviceCodeGenerator implements OAuth2TokenGenerator<OAuth2DeviceCode> {

		private final StringKeyGenerator deviceCodeGenerator = new Base64StringKeyGenerator(
				Base64.getUrlEncoder().withoutPadding(), 96);

		@Override
		public @Nullable OAuth2DeviceCode generate(OAuth2TokenContext context) {
			if (context.getTokenType() == null
					|| !OAuth2ParameterNames.DEVICE_CODE.equals(context.getTokenType().getValue())) {
				return null;
			}
			Instant issuedAt = Instant.now();
			Instant expiresAt = issuedAt
				.plus(context.getRegisteredClient().getTokenSettings().getDeviceCodeTimeToLive());
			return new OAuth2DeviceCode(this.deviceCodeGenerator.generateKey(), issuedAt, expiresAt);
		}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Fix the device client request: send all required parameters (client_id, scope if configured) as application/x-www-form-urlencoded form parameters.
  2. Return the error code/description from the OAuth2AuthenticationException response body to the client so it can correct the request.
  3. If you wrote a custom authentication converter for the device authorization endpoint, ensure it extracts the same parameters the default one does.
  4. Verify registeredClient scopes match what the device client requests.

Example fix

// before
curl -X POST https://as.example.com/oauth2/device_authorization  # no params
// after
curl -X POST https://as.example.com/oauth2/device_authorization \
  -d "client_id=device-client" -d "scope=device.scope"
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(clientId, "client_id is required");
if (scope != null && !scope.matches("[\x20-\x7E]+")) {
    throw new IllegalArgumentException("Invalid scope parameter");
}

Try / catch

try {
    return deviceAuthorizationEndpoint.process(converter.convert(request));
} catch (OAuth2AuthenticationException e) {
    return ResponseEntity.badRequest().body(Map.of(
        "error", e.getError().getErrorCode(),
        "error_description", e.getError().getDescription()));
}

Prevention

When it happens

Trigger: authenticate() validating the device authorization request: a required OAuth 2.0 parameter (such as client_id or scope) is absent or invalid; throwError(errorCode, parameterName) is invoked with that parameter name.

Common situations: Device clients sending malformed POSTs to /oauth2/device_authorization (missing client_id, wrong content-type, parameters in the wrong place); custom authentication converters dropping parameters; clients sending unsupported scope values.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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