apereo/cas · warning

Authentication request does not include the

Error message

Authentication request does not include the [{}] scope. CAS will not produce an ID token without this scope.

What it means

CAS only issues an OIDC ID token when the authorization request granted the 'openid' scope. If the access token tied to the IdTokenGenerationContext lacks the openid scope, ID token generation is skipped with this warning and a null token is returned, so the client receives no ID token.

Solutions

  1. Add scope=openid to the client's authorization request URL.
  2. Ensure the OIDC registered service definition includes 'openid' in its supported scopes.
  3. Verify the client's registered scope grant/policy allows openid.
  4. If the client intentionally wants only an access token, this warning is expected; include openid or use a plain OAuth2 flow instead.
  5. Confirm the flow passes IdTokenGenerationContext with the same access token that carries the granted scopes.

Example fix

// before
GET /cas/oidc/authorize?client_id=app&response_type=code&redirect_uri=...
// after
GET /cas/oidc/authorize?client_id=app&response_type=code&scope=openid%20profile&redirect_uri=...
Defensive patterns

Strategy: validation

Validate before calling

// Before initiating the OIDC flow, assert the request includes the openid scope:
boolean hasOpenidScope(String authorizeUrl) {
    String decoded = java.net.URLDecoder.decode(authorizeUrl, java.nio.charset.StandardCharsets.UTF_8);
    return decoded.matches(".*scope=([^&]*\\bopenid\\b[^&]*).*");
}

Prevention

When it happens

Trigger: OidcIdTokenGeneratorService.generate is invoked (token endpoint, implicit/hybrid flow) and context.getAccessToken().getScopes() does not contain OidcConstants.StandardScopes.OPENID ('openid'); also fires when the registered service's scope filtering removed 'openid' from the granted scopes.

Common situations: Client app omits scope=openid from its authorize URL; the OIDC registered service definition's supportedScopes excludes 'openid'; client policy restricts the granted scopes; custom/integration code calls token generation with a token minted for a non-OpenID grant.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/54c6ee53eb06b485. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/token/OidcIdTokenGeneratorService.java:88

    public OidcIdTokenGeneratorService(final ObjectProvider<OidcConfigurationContext> configurationContext) {
        super(configurationContext);
    }

    private static void setClaim(final JwtClaims claims, final String claimName, final Object claimValue) {
        if (claimValue != null && StringUtils.isNotBlank(claimValue.toString())) {
            claims.setClaim(claimName, claimValue);
        }
    }

    @Audit(action = AuditableActions.OIDC_ID_TOKEN,
        actionResolverName = AuditActionResolvers.OIDC_ID_TOKEN_ACTION_RESOLVER,
        resourceResolverName = AuditResourceResolvers.OIDC_ID_TOKEN_RESOURCE_RESOLVER)
    @Override
    public @Nullable OidcIdToken generate(final IdTokenGenerationContext context) throws Throwable {
        Assert.isAssignable(OidcRegisteredService.class, context.getRegisteredService().getClass(),
            "Registered service instance is not registered as an OpenID Connect application");
        if (!context.getAccessToken().getScopes().contains(OidcConstants.StandardScopes.OPENID.getScope())) {
            LOGGER.warn("Authentication request does not include the [{}] scope. CAS will not produce an ID token without this scope.",
                OidcConstants.StandardScopes.OPENID.getScope());
            return null;
        }
        if (context.getGrantType() == OAuth20GrantTypes.JWT_BEARER
            && !getConfigurationContext().getCasProperties().getAuthn().getOidc().getIdToken().isGenerateForJwtBearerGrantType()) {
            LOGGER.debug("ID token generation for grant type [{}] is disabled. Skipping ID token generation.", OAuth20GrantTypes.JWT_BEARER);
            return null;
        }

        val claims = buildJwtClaims(context);
        var deviceSecret = StringUtils.EMPTY;
        if (context.getGrantType() == OAuth20GrantTypes.AUTHORIZATION_CODE
            && context.getAccessToken().getScopes().contains(OidcConstants.StandardScopes.DEVICE_SSO.getScope())
            && getConfigurationContext().getDiscoverySettings().isNativeSsoSupported()) {
            deviceSecret = getConfigurationContext().getDeviceSecretGenerator().generate();
            claims.setStringClaim(OidcConstants.DS_HASH, getConfigurationContext().getDeviceSecretGenerator().hash(deviceSecret));
            if (context.getAccessToken().getTicketGrantingTicket() != null) {
                val encoded = (byte[]) getConfigurationContext().getTicketRegistry().getCipherExecutor()

View on GitHub (pinned to e7288fc434)