apereo/cas · error · IllegalArgumentException

No metadata defined for entity

Error message

No metadata defined for entity

What it means

After locating the subordinate entity by ID, fetchEntityStatement() requires the subordinate's metadata payload to build the entity statement. If the loaded OidcFederationSubordinate has a null metadata field, this IllegalArgumentException is thrown indicating the subordinate definition is incomplete.

Solutions

  1. Add a valid metadata JSON object to the subordinate's JSON file in the subordinate directory and reload/restart
  2. Verify the JSON field names match OidcFederationSubordinate's expected metadata property for the current CAS version
  3. Validate each subordinate JSON against the model before deployment

Example fix

// before
{ "entityId": "https://op.example.org" }
// after
{ "entityId": "https://op.example.org",
  "metadata": { "openid_provider": { "issuer": "https://op.example.org", "authorization_endpoint": "..." } } }
Defensive patterns

Strategy: validation

Validate before calling

val found = repository.findSubordinateByEntityId(entityId);
if (found == null || found.getMetadata() == null) {
    throw new IllegalStateException("Subordinate missing metadata: " + 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: The subordinate JSON file in the subordinate directory parses successfully but lacks the metadata property, and a client requests a fetch-entity statement for that entity ID.

Common situations: Hand-authored subordinate JSON missing the metadata block; schema change/version upgrade renamed or moved the metadata field so Jackson leaves it null; entity registered as a pure metadata placeholder.

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/fbfa4c60b6fd95ec. 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:84

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

        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)