{"record":{"id":"3ad6e01d44535407","repo":"spring-projects/spring-security","slug":"invalid-scope-3ad6e0","errorCode":"invalid_scope","errorMessage":"Invalid Client Registration: scope","messagePattern":"Invalid Client Registration: scope","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":400,"severity":"error","filePath":"oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationValidator.java","lineNumber":285,"sourceCode":"\t\t\tthrow createException(\"invalid_client_metadata\", OidcClientMetadataClaimNames.JWKS_URI);\n\t\t}\n\t}\n\n\tprivate static void validateJwkSetUriSimple(OidcClientRegistrationAuthenticationContext authenticationContext) {\n\t\t// No validation. Preserves prior behavior.\n\t}\n\n\tprivate static void validateScope(OidcClientRegistrationAuthenticationContext authenticationContext) {\n\t\tOidcClientRegistrationAuthenticationToken clientRegistrationAuthentication = authenticationContext\n\t\t\t.getAuthentication();\n\t\tAssert.notNull(clientRegistrationAuthentication.getClientRegistration(), \"clientRegistration cannot be null\");\n\t\tList<String> scopes = clientRegistrationAuthentication.getClientRegistration().getScopes();\n\t\tif (!CollectionUtils.isEmpty(scopes)) {\n\t\t\tif (LOGGER.isDebugEnabled()) {\n\t\t\t\tLOGGER.debug(LogMessage.format(\n\t\t\t\t\t\t\"Invalid request: scope must not be set during Dynamic Client Registration ('%s')\", scopes));\n\t\t\t}\n\t\t\tthrow createException(OAuth2ErrorCodes.INVALID_SCOPE, OidcClientMetadataClaimNames.SCOPE);\n\t\t}\n\t}\n\n\tprivate static void validateScopeSimple(OidcClientRegistrationAuthenticationContext authenticationContext) {\n\t\t// No validation. Preserves prior behavior.\n\t}\n\n\tprivate static boolean isUnsafeScheme(String scheme) {\n\t\treturn \"javascript\".equalsIgnoreCase(scheme) || \"data\".equalsIgnoreCase(scheme)\n\t\t\t\t|| \"vbscript\".equalsIgnoreCase(scheme);\n\t}\n\n\tprivate static OAuth2AuthenticationException createException(String errorCode, String fieldName) {\n\t\tOAuth2Error error = new OAuth2Error(errorCode, \"Invalid Client Registration: \" + fieldName, ERROR_URI);\n\t\tthrow new OAuth2AuthenticationException(error);\n\t}\n\n}","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcClientRegistrationAuthenticationValidator.java#L267-L303","documentation":"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.","triggerScenarios":"Sending client registration metadata with a non-empty 'scope' array during dynamic client registration (OidcClientRegistrationAuthenticationToken carrying a client registration whose getScopes() is not empty).","commonSituations":"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.","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"],"exampleFix":"// before\n{\"client_name\": \"my-app\", \"scope\": [\"openid\", \"profile\"], \"redirect_uris\": [...], ...}\n// after\n{\"client_name\": \"my-app\", \"redirect_uris\": [...], ...} // set scopes server-side","handlingStrategy":"validation","validationCode":"if (registration.getScopes() != null && !registration.getScopes().isEmpty()) {\n    throw new IllegalArgumentException(\"scope must not be sent during dynamic client registration\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["oauth2","oidc","client-registration","scope"],"backgroundTag":"invalid-argument-value","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}