spring-projects/spring-security · error · OAuth2AuthenticationException
invalid_scope
invalid_scope
Error message
Invalid Client Registration: scope
What it means
OIDC Dynamic Client Registration with this validator forbids the scope claim: scopes are not settable through dynamic registration. If the registration request contains a non-empty scope array, validateScope throws invalid_scope for the scope field.
Source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationValidator.java:285
throw createException("invalid_client_metadata", OidcClientMetadataClaimNames.JWKS_URI);
}
}
private static void validateJwkSetUriSimple(OidcClientRegistrationAuthenticationContext authenticationContext) {
// No validation. Preserves prior behavior.
}
private static void validateScope(OidcClientRegistrationAuthenticationContext authenticationContext) {
OidcClientRegistrationAuthenticationToken clientRegistrationAuthentication = authenticationContext
.getAuthentication();
Assert.notNull(clientRegistrationAuthentication.getClientRegistration(), "clientRegistration cannot be null");
List<String> scopes = clientRegistrationAuthentication.getClientRegistration().getScopes();
if (!CollectionUtils.isEmpty(scopes)) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(LogMessage.format(
"Invalid request: scope must not be set during Dynamic Client Registration ('%s')", scopes));
}
throw createException(OAuth2ErrorCodes.INVALID_SCOPE, OidcClientMetadataClaimNames.SCOPE);
}
}
private static void validateScopeSimple(OidcClientRegistrationAuthenticationContext authenticationContext) {
// No validation. Preserves prior behavior.
}
private static boolean isUnsafeScheme(String scheme) {
return "javascript".equalsIgnoreCase(scheme) || "data".equalsIgnoreCase(scheme)
|| "vbscript".equalsIgnoreCase(scheme);
}
private static OAuth2AuthenticationException createException(String errorCode, String fieldName) {
OAuth2Error error = new OAuth2Error(errorCode, "Invalid Client Registration: " + fieldName, ERROR_URI);
throw new OAuth2AuthenticationException(error);
}
}View on GitHub (pinned to 96852e8860)
Solutions
- Remove the scope field from the dynamic client registration request
- Configure the client's scopes server-side after registration (e.g. via RegisteredClientRepository / admin flow)
- If scopes must be registrable, use the simple validation configuration instead of strict OIDC registration validation
Example fix
// before
{"client_name": "my-app", "scope": ["openid", "profile"], "redirect_uris": [...], ...}
// after
{"client_name": "my-app", "redirect_uris": [...], ...} // set scopes server-side Defensive patterns
Strategy: validation
Validate before calling
if (registration.getScopes() != null && !registration.getScopes().isEmpty()) {
throw new IllegalArgumentException("scope must not be sent during dynamic client registration");
} Prevention
- Build dynamic-registration payloads from scratch, not by reusing static client config objects
- Assign scopes via server-side administration after registration
- Document that scope is server-managed for dynamic clients
When it happens
Trigger: Sending client registration metadata with a non-empty 'scope' array during dynamic client registration (OidcClientRegistrationAuthenticationToken carrying a client registration whose getScopes() is not empty).
Common situations: Reusing a static-client JSON template (which normally includes scope) as a dynamic-registration payload; migration scripts that copy RegisteredClient settings wholesale into registration requests; recent versions made dynamic registration stricter than older permissive behavior.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- invalid_scope
- server_error
- Invalid Client Registration: + fieldName
- Invalid Client Registration: + fieldName
- insufficient_scope
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/3ad6e01d44535407.
Report an issue: GitHub.