apereo/cas · error · IllegalArgumentException

Federation role [ ] is not supported for OpenID Provider

Error message

Federation role [%s] is not supported for OpenID Provider

What it means

The .well-known/openid-federation discovery controller serves OP metadata only when the deployment role is OPENID_PROVIDER. If server discovery settings are present but role != OPENID_PROVIDER, it throws this IllegalArgumentException naming the configured role.

Solutions

  1. Set cas.oidc.federation.role=OPENID_PROVIDER when serving OP discovery metadata
  2. Remove/adjust the OP server discovery settings if this deployment should be TRUST_ANCHOR or INTERMEDIATE only
  3. Split OP and federation-entity roles into separate deployments

Example fix

// before
cas.oidc.federation.role=TRUST_ANCHOR
# ...OP discovery settings still configured...
// after
cas.oidc.federation.role=OPENID_PROVIDER
Defensive patterns

Strategy: validation

Validate before calling

val role = oidcProperties.getFederation().getRole();
if (serverDiscoverySettingsPresent && role != OidcFederationRole.OPENID_PROVIDER) {
    throw new IllegalStateException("OP discovery settings present but role is " + role);
}

Prevention

When it happens

Trigger: CAS started with OP server discovery settings available (OP metadata bean present) while cas.oidc.federation.role is TRUST_ANCHOR or INTERMEDIATE, and the well-known federation endpoint is hit.

Common situations: Federating OP deployment forgot to set role=OPENID_PROVIDER; role later changed to intermediate/trust-anchor but OP metadata configuration left in place; conflicting federation/OP settings in the same deployment.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-oidc-federation/src/main/java/org/apereo/cas/oidc/federation/web/OidcWellKnownFederationEndpointController.java:72

        description = "Handles requests for well-known OIDC discovery federation configuration")
    public ResponseEntity getWellKnownDiscoveryConfiguration(
        final HttpServletRequest request, final HttpServletResponse response) throws Exception {

        LOGGER.info("Generating federation entity statement");

        val error = retrieveInvalidIssuerError(request, response, OidcConstants.FETCH_FEDERATION_URL);
        if (error != null) {
            return error;
        }

        val role = oidcProperties.getFederation().getRole();
        val settings = serverDiscoverySettings.getIfAvailable();
        var issuer = oidcProperties.getCore().getIssuer();
        val metadata = new JSONObject();
        val authorityHints = oidcProperties.getFederation().getAuthorityHints().stream().map(EntityID::new).toList();
        if (settings != null) {
            if (role != OidcFederationRole.OPENID_PROVIDER) {
                throw new IllegalArgumentException("Federation role [" + role + "] is not supported for OpenID Provider");
            }
            issuer = settings.getIssuer();

            if (authorityHints.isEmpty()) {
                throw new IllegalArgumentException("OpenID provider requires authority hint(s)");
            }

            val json = JSONValue.parse(settings.toJson());
            metadata.put(EntityType.OPENID_PROVIDER.getValue(), json);

        } else if (role == OidcFederationRole.INTERMEDIATE) {
            if (authorityHints.isEmpty()) {
                throw new IllegalArgumentException("Intermediate requires authority hint(s)");
            }

        } else if (role == OidcFederationRole.TRUST_ANCHOR) {
            if (!authorityHints.isEmpty()) {
                throw new IllegalArgumentException("Trust anchor requires no authority hints");

View on GitHub (pinned to e7288fc434)