OAuth2: invalid_scope
Hydra rejected the requested scope
{
"error": "invalid_scope",
"error_description": "The requested scope is invalid, unknown, malformed, or exceeds the scope granted by the resource owner."
}Cause 1: Scope not in client's allowed list
Each Hydra client has a list of scopes it can request. If you ask for one that isn't there, rejected.
hydra get client <id> | jq .scope
# e.g. "openid offline_access api:read"If your app asks for api:write but it's not listed → invalid_scope.
Fix:
hydra update client <id> --scope "openid offline_access api:read api:write"Note: changing scopes affects what users can grant via consent screen. Existing tokens are unaffected (their scopes are baked in).
Cause 2: Scope mistyped
Common typos:
open_idinstead ofopenid.offline access(space) instead ofoffline_access.email profilevsemail,profile(must be space-delimited in URL).
The OAuth2 spec uses space-delimited:
&scope=openid%20profile%20emailCause 3: Scope contains invalid characters
Scope names are limited to printable ASCII excluding space, double-quote, backslash. Don't use Unicode or special chars.
Olympus convention: domain:action style (e.g., api:read, orders:write).
Cause 4: Scope policy explicitly denied
For policies via Cedar / OPA, your authz might deny a scope per the user / client combination. Check authz logs.
How to list valid scopes for a client
hydra get client <id> --format json | jq .scope | tr ' ' '\n'Universal scopes
These should be on most clients:
openid, required for OIDC (returns id_token).offline_access, required for refresh token.profile, basic claims.email, email claim.
Custom scopes for your API: [domain]:[action] e.g. billing:read, users:write.
Reduced scope on response
Hydra (and OAuth2 spec) allows the authorization server to grant less than requested. If client asks openid email api:admin and the user only consents to openid email, the token returns:
{ "access_token": "...", "scope": "openid email" }No error, but your app should check the returned scope, not assume what you asked for.