apereo/cas · error · IllegalArgumentException

Intermediate requires authority hint(s)

Error message

Intermediate requires authority hint(s)

What it means

An Intermediate entity, like an OP, must reference at least one superior entity via authority hints. The controller throws this IllegalArgumentException when the role is INTERMEDIATE but cas.oidc.federation.authority-hints is empty.

Solutions

  1. Add the parent trust anchor (or superior intermediate) entity ID(s) to cas.oidc.federation.authority-hints
  2. Verify the YAML/properties list actually parses to a non-empty collection (check indentation)
  3. Change role to TRUST_ANCHOR only if the entity really has no superior

Example fix

// before
cas.oidc.federation.role=INTERMEDIATE
# no authority-hints
// after
cas.oidc.federation.role=INTERMEDIATE
cas.oidc.federation.authority-hints=https://ta.example.org
Defensive patterns

Strategy: validation

Validate before calling

if (role == OidcFederationRole.INTERMEDIATE && oidcProperties.getFederation().getAuthorityHints().isEmpty()) {
    throw new IllegalStateException("Intermediate requires authority hints");
}

Prevention

When it happens

Trigger: Deployment role set to INTERMEDIATE with no authority-hints configured while the well-known federation metadata is being built.

Common situations: Intermediate registered directly under a trust anchor but the anchor's entity ID never added to config; YAML list syntax error producing an empty list.

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/f017f68580f66598. 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:85

        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");
            }

        } else {
            throw new IllegalArgumentException("Federation role [" + role + "] is not supported for Trust Anchor/Intermediate");
        }

        val federationMetadata = buildMetadata(issuer);
        metadata.put(EntityType.FEDERATION_ENTITY.getValue(), federationMetadata.toJSONObject());

        return buildEntityStatement(issuer, issuer, metadata, null, authorityHints);
    }
}

View on GitHub (pinned to e7288fc434)