spring-projects/spring-security · error · OAuth2AuthenticationException
invalid_scope
invalid_scope
Error message
Invalid Client Registration: scope
What it means
Dynamic Client Registration (RFC 7591) as implemented here does not allow the client to pre-specify scopes: validateScope throws invalid_scope for the scope claim if the registration request contains a non-empty scope list. The authorization server controls scopes itself; a client registration carrying scope is rejected.
Source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2ClientRegistrationAuthenticationValidator.java:225
}
throw createException("invalid_client_metadata", OAuth2ClientMetadataClaimNames.JWKS_URI);
}
}
private static void validateJwkSetUriSimple(OAuth2ClientRegistrationAuthenticationContext authenticationContext) {
// No validation. Preserves prior behavior.
}
private static void validateScope(OAuth2ClientRegistrationAuthenticationContext authenticationContext) {
OAuth2ClientRegistrationAuthenticationToken clientRegistrationAuthentication = authenticationContext
.getAuthentication();
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, OAuth2ClientMetadataClaimNames.SCOPE);
}
}
private static void validateScopeSimple(OAuth2ClientRegistrationAuthenticationContext 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 client registration request body
- If per-client scopes are needed, configure the authorization server to assign scopes upon registration (custom client mapping / RegistrationClientScope) instead of the request
- Verify which validator mode the server runs (validateScope vs validateScopeSimple — the simple variant preserves prior permissive behavior)
Example fix
// before
{"client_name": "demo", "redirect_uris": ["https://app/cb"], "scope": "message.read"}
// after
{"client_name": "demo", "redirect_uris": ["https://app/cb"]} Defensive patterns
Strategy: validation
Validate before calling
if (registrationJson.has("scope") && !registrationJson.isNull("scope")) throw new IllegalArgumentException("scope must not be sent in dynamic client registration"); Type guard
boolean scopeFreeRegistration(java.util.Map<String,Object> body) {
return body.get("scope") == null || body.get("scope").toString().isEmpty();
} Try / catch
catch (OAuth2ErrorResponseException e) { if ("invalid_scope".equals(e.getError().getErrorCode())) { /* drop the scope field and retry */ } } Prevention
- Omit the scope field entirely from RFC 7591 registration payloads
- Configure scopes server-side (custom registration mapping) rather than in the request
- Strip scope from migrated registration templates coming from other OAuth2 servers
When it happens
Trigger: POSTing a client registration JSON that includes a 'scope' field (e.g. "scope": "message.read message.write") to the registration endpoint when strict validation is enabled.
Common situations: Migrating from other OAuth2 servers (e.g. Keycloak, Okta) where scope in registration is allowed; copying authorization-request style payloads into the registration request; templated registration clients that always include scope.
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
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/ab0a08e6424bfd7b.
Report an issue: GitHub.