{"record":{"id":"37a9bce1c5a35eca","repo":"spring-projects/spring-security","slug":"invalid-scope-37a9bc","errorCode":"invalid_scope","errorMessage":"OAuth 2.0 Parameter: scope","messagePattern":"OAuth 2\\.0 Parameter: scope","errorType":"error_code","errorClass":"OAuth2AuthorizationCodeRequestAuthenticationException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationValidator.java","lineNumber":201,"sourceCode":"\t\t\t\t\t\tauthorizationCodeRequestAuthentication, registeredClient);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static void validateScope(OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {\n\t\tOAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication = authenticationContext\n\t\t\t.getAuthentication();\n\t\tRegisteredClient registeredClient = authenticationContext.getRegisteredClient();\n\n\t\tSet<String> requestedScopes = authorizationCodeRequestAuthentication.getScopes();\n\t\tSet<String> allowedScopes = registeredClient.getScopes();\n\t\tif (!requestedScopes.isEmpty() && !allowedScopes.containsAll(requestedScopes)) {\n\t\t\tif (LOGGER.isDebugEnabled()) {\n\t\t\t\tLOGGER.debug(\n\t\t\t\t\t\tLogMessage.format(\"Invalid request: requested scope is not allowed for registered client '%s'\",\n\t\t\t\t\t\t\t\tregisteredClient.getId()));\n\t\t\t}\n\t\t\tthrow createException(OAuth2ErrorCodes.INVALID_SCOPE, OAuth2ParameterNames.SCOPE,\n\t\t\t\t\tauthorizationCodeRequestAuthentication, registeredClient);\n\t\t}\n\t}\n\n\tprivate static void validateCodeChallenge(\n\t\t\tOAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext) {\n\t\tOAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication = authenticationContext\n\t\t\t.getAuthentication();\n\t\tRegisteredClient registeredClient = authenticationContext.getRegisteredClient();\n\n\t\t// code_challenge (REQUIRED for public clients) - RFC 7636 (PKCE)\n\t\tString codeChallenge = (String) authorizationCodeRequestAuthentication.getAdditionalParameters()\n\t\t\t.get(PkceParameterNames.CODE_CHALLENGE);\n\t\tif (StringUtils.hasText(codeChallenge)) {\n\t\t\tString codeChallengeMethod = (String) authorizationCodeRequestAuthentication.getAdditionalParameters()\n\t\t\t\t.get(PkceParameterNames.CODE_CHALLENGE_METHOD);\n\t\t\tif (!StringUtils.hasText(codeChallengeMethod) || !\"S256\".equals(codeChallengeMethod)) {\n\t\t\t\tthrow createException(OAuth2ErrorCodes.INVALID_REQUEST, PkceParameterNames.CODE_CHALLENGE_METHOD,","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2AuthorizationCodeRequestAuthenticationValidator.java#L183-L219","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Add the requested scopes to the client's RegisteredClient via RegisteredClient.Builder.scope(...)","Remove the unregistered scopes from the authorization request so it only asks for allowed scopes","Check server logs (debug enabled: 'requested scope is not allowed for registered client') to identify the exact offending scope"],"exampleFix":"// before\nRegisteredClient.withId(id).clientId(\"client\").scope(\"read\").build();\n// request asks scope=read write -> rejected\n// after\nRegisteredClient.withId(id).clientId(\"client\").scope(\"read\").scope(\"write\").build();","handlingStrategy":"validation","validationCode":"const disallowed = requestedScopes.filter(s => !registeredClientScopes.includes(s));\nif (disallowed.length) throw new Error(`scopes not registered for client: ${disallowed.join(',')}`);","typeGuard":"function isSubsetOf(requested, allowed) {\n  return requested.every(s => allowed.includes(s));\n}","tryCatchPattern":"try {\n  return await authorize(params);\n} catch (e) {\n  if (e.error === 'invalid_scope') {\n    console.error('Unsupported scopes:', params.scope);\n    params.scope = params.scope.filter(s => allowedScopes.includes(s));\n    return await authorize(params);\n  }\n  throw e;\n}","preventionTips":["Generate the client's scope list from a shared config consumed by both server registration and client requests","Diff requested vs registered scopes in CI before deployments","Never copy scope strings between clients without checking registration"],"tags":["oauth2","scope","authorization-request"],"backgroundTag":"invalid-oauth-scope","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}