spring-projects/spring-security · error · OAuth2AuthenticationException

OAuth 2.0 Token Introspection Parameter: ${parameterName}

Error message

OAuth 2.0 Token Introspection Parameter: ${parameterName}

What it means

The OAuth2TokenIntrospectionAuthenticationConverter throws this when a required Token Introspection request parameter (per RFC 7662 section 2.1) is missing or appears more than once in the request. The message embeds the offending parameterName so the client knows which parameter failed. It surfaces as an OAuth2AuthenticationException handled by the authorization server's error endpoint, producing an OAuth2 error response.

Source

Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2TokenIntrospectionAuthenticationConverter.java:89

		Map<String, Object> additionalParameters = new HashMap<>();
		parameters.forEach((key, value) -> {
			if (!key.equals(OAuth2ParameterNames.TOKEN) && !key.equals(OAuth2ParameterNames.TOKEN_TYPE_HINT)) {
				additionalParameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0]));
			}
		});

		Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication();
		Assert.notNull(clientPrincipal, "clientPrincipal cannot be null");

		return new OAuth2TokenIntrospectionAuthenticationToken(token, clientPrincipal, tokenTypeHint,
				additionalParameters);
	}

	private static void throwError(String errorCode, String parameterName) {
		OAuth2Error error = new OAuth2Error(errorCode, "OAuth 2.0 Token Introspection Parameter: " + parameterName,
				"https://datatracker.ietf.org/doc/html/rfc7662#section-2.1");
		throw new OAuth2AuthenticationException(error);
	}

}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Ensure the introspection request includes exactly one 'token' form parameter and, if sent, exactly one 'token_type_hint' (access_token or refresh_token).
  2. Send parameters as application/x-www-form-urlencoded in the request body, not duplicated in the query string.
  3. Inspect the error detail to identify the offending parameterName and log the raw request body to spot duplicates.
  4. If a proxy/gateway is in the path, verify it does not re-append or duplicate parameters.

Example fix

// before
form.set('token', token);
form.set('token', token); // duplicate -> invalid_request
// after
form.set('token', token);
form.set('token_type_hint', 'access_token');
Defensive patterns

Strategy: validation

Validate before calling

const params = new URLSearchParams(body);
if (params.getAll('token').length !== 1 || !params.get('token')) {
  throw new Error('introspection requires exactly one non-empty token parameter');
}
const hint = params.getAll('token_type_hint');
if (hint.length > 1 || (hint[0] && !['access_token','refresh_token'].includes(hint[0]))) {
  throw new Error('invalid token_type_hint');
}

Type guard

function hasSingleParam(params, name) {
  const values = params.getAll(name);
  return values.length === 1 && values[0].length > 0;
}

Try / catch

try {
  const response = await fetch('/oauth2/introspect', { method: 'POST', body });
  const data = await response.json();
  if (data.error === 'invalid_request') {
    console.error('Introspection parameter error:', data.error_description);
  }
} catch (e) { /* network/handling */ }

Prevention

When it happens

Trigger: POST to /oauth2/introspect without the required 'token' parameter, or with duplicated parameters (e.g. token=abc&token=def), or missing/invalid 'token_type_hint' value; throwError is called from convert() when parameter extraction/validation fails.

Common situations: Clients sending form-encoded introspection requests with the token omitted or repeated; proxies or HTTP client libraries that flatten/duplicate query or form parameters; misconfigured clients that put parameters in the wrong place (query string vs form body); custom frontends forwarding malformed introspection requests.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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