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
- Ensure the introspection request includes exactly one 'token' form parameter and, if sent, exactly one 'token_type_hint' (access_token or refresh_token).
- Send parameters as application/x-www-form-urlencoded in the request body, not duplicated in the query string.
- Inspect the error detail to identify the offending parameterName and log the raw request body to spot duplicates.
- 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
- Always send introspection parameters as a form-encoded body with a single token value.
- Build the request with URLSearchParams or an equivalent library to avoid manual encoding duplicates.
- Never put introspection parameters in the query string.
- Log the raw request body in tests to catch duplicates introduced by interceptors or proxies.
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
- An error occurred reading the Token Introspection Response:
- An error occurred writing the Token Introspection Response:
- invalid_request
- invalid_request
- OAuth 2.0 Token Revocation Parameter: ${parameterName}
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/6a98aaab4b080520.
Report an issue: GitHub.