apereo/cas · warning
Provided scopes [ ] are undefined by OpenID Connect, which…
Error message
Provided scopes [{}] are undefined by OpenID Connect, which requires that scope [{}] MUST be specified, or the behavior is unspecified. CAS MAY allow this request to be processed for now. What it means
The OIDC specification requires that every authorization request include the 'openid' scope. CAS resolves the requested scopes and logs a warning if the scope set is empty or lacks 'openid'; it does not hard-fail (the spec says CAS MAY still process the request). This is a compliance warning, not a rejection.
Solutions
- Add 'openid' to the scope parameter of the authorization request
- Ensure the RP library defaults include the openid scope for OIDC flows
- Keep scope values space-delimited and URL-encoded properly (scope=openid%20profile)
- If purely OAuth2 (non-OIDC) usage is intended, use the plain /oauth2.0/authorize endpoint instead
Example fix
// before GET /oidc/authorize?client_id=client&response_type=code&scope=profile&redirect_uri=... // after GET /oidc/authorize?client_id=client&response_type=code&scope=openid%20profile&redirect_uri=...
Defensive patterns
Strategy: validation
Validate before calling
const scopes = (params.get('scope') ?? '').split(' ').filter(Boolean);
if (!scopes.includes('openid')) throw new Error('OIDC authorization requests must include scope "openid"'); Type guard
function hasOpenIdScope(scopeStr) {
return typeof scopeStr === 'string' && scopeStr.split(' ').includes('openid');
} Prevention
- Always prepend 'openid' to the scope list in OIDC clients
- Check RP library defaults for scope
- Use space-delimited, URL-encoded scope values
- Use /oauth2.0 endpoints for pure OAuth2 flows without openid
When it happens
Trigger: Any authorization request (or PAR request reaching authorize) whose resolved scope list is empty or does not contain the 'openid' scope, e.g. scope=profile email or no scope at all.
Common situations: RP libraries defaulting to plain OAuth2 scope requests; developers testing with only 'profile'; clients copying OAuth2 examples that omit scope; PAR flows dropping the scope parameter.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Authentication request does not include the
- JWKS cannot contain expressions
- Unable to use 'none' as introspection signing algorithm
- Unable to use 'none' as introspection encryption algorithm
- Unable to use 'none' for the user-info signing algorithm
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/41bbd288c09b87ed.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/web/controllers/authorize/OidcAuthorizeEndpointController.java:57
@Operation(summary = "Handle OIDC authorization request")
@Override
public ModelAndView handleRequest(final HttpServletRequest request, final HttpServletResponse response) throws Throwable {
val webContext = new JEEContext(request, response);
if (!getConfigurationContext().getIssuerService().validateIssuer(webContext, List.of(OidcConstants.AUTHORIZE_URL, OAuth20Constants.AUTHORIZE_URL))) {
LOGGER.warn("CAS cannot accept the authorization request given the issuer is invalid.");
return OAuth20Utils.writeError(response, OAuth20Constants.INVALID_REQUEST, "Invalid issuer");
}
if (getConfigurationContext().getDiscoverySettings().isRequirePushedAuthorizationRequests()
&& webContext.getRequestURL().endsWith(OidcConstants.AUTHORIZE_URL)
&& StringUtils.isBlank(request.getParameter(OidcConstants.REQUEST_URI))) {
LOGGER.warn("CAS is configured to only accept pushed authorization requests");
return OAuth20Utils.produceUnauthorizedErrorView(HttpStatus.FORBIDDEN);
}
val scopes = getConfigurationContext().getRequestParameterResolver().resolveRequestedScopes(webContext);
if (scopes.isEmpty() || !scopes.contains(OidcConstants.StandardScopes.OPENID.getScope())) {
LOGGER.warn("Provided scopes [{}] are undefined by OpenID Connect, which requires that scope [{}] MUST be specified, "
+ "or the behavior is unspecified. CAS MAY allow this request to be processed for now.",
scopes, OidcConstants.StandardScopes.OPENID.getScope());
}
return super.handleRequest(request, response);
}
@PostMapping({
'/' + OidcConstants.BASE_OIDC_URL + '/' + OAuth20Constants.AUTHORIZE_URL,
"/**/" + OidcConstants.AUTHORIZE_URL
})
@Override
@Operation(summary = "Handle OIDC authorization request")
public ModelAndView handleRequestPost(final HttpServletRequest request,
final HttpServletResponse response) throws Throwable {
return handleRequest(request, response);
}
}
View on GitHub (pinned to e7288fc434)