apereo/cas · error · IllegalArgumentException

No federation keys defined for entity

Error message

No federation keys defined for entity

What it means

fetchEntityStatement() also requires the subordinate's federation keys to sign/build the entity statement. If federationKeys is null or empty on the loaded subordinate, this IllegalArgumentException is thrown because an entity statement without signing keys cannot be produced.

Solutions

  1. Add the entity's public JWK set to the subordinate JSON's federation-keys field and reload
  2. Generate a keypair and publish its public JWK into the subordinate definition if none exists
  3. Confirm the JSON property name matches OidcFederationSubordinate.getFederationKeys() binding

Example fix

// before
{ "entityId": "https://op.example.org", "metadata": {...} }
// after
{ "entityId": "https://op.example.org", "metadata": {...},
  "federationKeys": { "keys": [ { "kty": "RSA", "kid": "sig-1", "n": "...", "e": "AQAB" } ] } }
Defensive patterns

Strategy: validation

Validate before calling

val found = repository.findSubordinateByEntityId(entityId);
if (found == null || found.getFederationKeys() == null || found.getFederationKeys().isEmpty()) {
    throw new IllegalStateException("Subordinate missing federation keys: " + entityId);
}

Try / catch

try {
    return controller.fetchEntityStatement(sub, request, response);
} catch (IllegalArgumentException e) {
    return ResponseEntity.badRequest().body(Map.of("error", "invalid_request", "detail", e.getMessage()));
}

Prevention

When it happens

Trigger: A fetch-entity request targets a subordinate whose JSON definition omits the federation-keys collection (or defines an empty list).

Common situations: Subordinate file created from a template without keys; keys removed during rotation but file not updated; typo in the JSON key so Jackson binds an empty/null 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/32994e985e9245b0. Report an issue: GitHub.

Appendix: source

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

        }

        if (StringUtils.isBlank(sub)) {
            val body = OAuth20Utils.getErrorResponseBody(OAuth20Constants.INVALID_REQUEST, "Invalid entity");
            return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
        }

        val foundSubordinate = subordinateRepository.getSubordinates().get(sub);
        if (foundSubordinate == null) {
            val body = OAuth20Utils.getErrorResponseBody(OAuth20Constants.INVALID_REQUEST, "Invalid entity");
            return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
        }
        val serviceMetadata = foundSubordinate.getMetadata();
        if (serviceMetadata == null) {
            throw new IllegalArgumentException("No metadata defined for entity");
        }
        val federationKeys = foundSubordinate.getFederationKeys();
        if (federationKeys == null || federationKeys.isEmpty()) {
            throw new IllegalArgumentException("No federation keys defined for entity");
        }

        val issuer = oidcProperties.getCore().getIssuer();
        val metadata = (JSONObject) JSONValue.parse(serviceMetadata.toString());
        return buildEntityStatement(issuer, sub, metadata, federationKeys, null);
    }
}

View on GitHub (pinned to e7288fc434)