spring-projects/spring-security · error · OAuth2AuthorizationCodeRequestAuthenticationException

invalid_scope

invalid_scope

Error message

OAuth 2.0 Parameter: scope

What it means

The authorization server validates that every scope requested in the authorization code request is allowed for the registered client. If the request asks for scopes that are not in the client's RegisteredClient.getScopes() set, the request is rejected with invalid_scope and the 'scope' parameter is named in the error.

Source

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

						authorizationCodeRequestAuthentication, registeredClient);
			}
		}
	}

	private static void validateScope(OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {
		OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication = authenticationContext
			.getAuthentication();
		RegisteredClient registeredClient = authenticationContext.getRegisteredClient();

		Set<String> requestedScopes = authorizationCodeRequestAuthentication.getScopes();
		Set<String> allowedScopes = registeredClient.getScopes();
		if (!requestedScopes.isEmpty() && !allowedScopes.containsAll(requestedScopes)) {
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug(
						LogMessage.format("Invalid request: requested scope is not allowed for registered client '%s'",
								registeredClient.getId()));
			}
			throw createException(OAuth2ErrorCodes.INVALID_SCOPE, OAuth2ParameterNames.SCOPE,
					authorizationCodeRequestAuthentication, registeredClient);
		}
	}

	private static void validateCodeChallenge(
			OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {
		OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication = authenticationContext
			.getAuthentication();
		RegisteredClient registeredClient = authenticationContext.getRegisteredClient();

		// code_challenge (REQUIRED for public clients) - RFC 7636 (PKCE)
		String codeChallenge = (String) authorizationCodeRequestAuthentication.getAdditionalParameters()
			.get(PkceParameterNames.CODE_CHALLENGE);
		if (StringUtils.hasText(codeChallenge)) {
			String codeChallengeMethod = (String) authorizationCodeRequestAuthentication.getAdditionalParameters()
				.get(PkceParameterNames.CODE_CHALLENGE_METHOD);
			if (!StringUtils.hasText(codeChallengeMethod) || !"S256".equals(codeChallengeMethod)) {
				throw createException(OAuth2ErrorCodes.INVALID_REQUEST, PkceParameterNames.CODE_CHALLENGE_METHOD,

View on GitHub (pinned to 96852e8860)

Solutions

  1. Add the requested scopes to the client's RegisteredClient via RegisteredClient.Builder.scope(...)
  2. Remove the unregistered scopes from the authorization request so it only asks for allowed scopes
  3. Check server logs (debug enabled: 'requested scope is not allowed for registered client') to identify the exact offending scope

Example fix

// before
RegisteredClient.withId(id).clientId("client").scope("read").build();
// request asks scope=read write -> rejected
// after
RegisteredClient.withId(id).clientId("client").scope("read").scope("write").build();
Defensive patterns

Strategy: validation

Validate before calling

const disallowed = requestedScopes.filter(s => !registeredClientScopes.includes(s));
if (disallowed.length) throw new Error(`scopes not registered for client: ${disallowed.join(',')}`);

Type guard

function isSubsetOf(requested, allowed) {
  return requested.every(s => allowed.includes(s));
}

Try / catch

try {
  return await authorize(params);
} catch (e) {
  if (e.error === 'invalid_scope') {
    console.error('Unsupported scopes:', params.scope);
    params.scope = params.scope.filter(s => allowedScopes.includes(s));
    return await authorize(params);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling GET /oauth2/authorize with a scope parameter containing any value not present in the RegisteredClient's registered scopes (requestedScopes not a subset of allowedScopes).

Common situations: Client config drifted from what the frontend requests (e.g. frontend asks for 'read:profile' but client registered only 'profile'); copy-pasting scopes from another client; renaming scopes server-side without updating clients.

Related errors


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