apereo/cas · warning
Realm [ ] doesn't match with configured realm [ ]
Error message
Realm [{}] doesn't match with configured realm [{}] What it means
WrappingSecurityTokenServiceClaimsHandler.retrieveClaimValues only issues claims when the realm in the incoming ClaimsParameters matches the handler's configured realm (case-insensitive). On mismatch (or a null realm) it logs this warning and returns an empty ProcessedClaimCollection instead of claims. This is a guard so one handler only serves its own realm in a multi-realm STS deployment.
Solutions
- Set the claims handler's realm to exactly match the realm string produced by the STS realm parser for the request (compare log values; they are printed).
- Configure the realm parser (e.g. UriRealmParser realmMap) so the requested URI maps to the expected realm instead of null/another name.
- If the handler should serve all realms, register the handler without a realm restriction or add one handler instance per realm.
- Use the returned empty claim collection as a signal: enable debug logging to trace which realm string each side computes.
Example fix
// before
handler.setHandlerRealm("REALM_A"); // requests arrive for realm "B"
// after
handler.setHandlerRealm("REALM_B"); // matches parameters.getRealm() Defensive patterns
Strategy: validation
Validate before calling
if (parameters.getRealm() == null || !parameters.getRealm().equalsIgnoreCase(handlerRealm)) {
throw new IllegalStateException("Realm mismatch: request=" + parameters.getRealm() + " handler=" + handlerRealm);
} Type guard
boolean realmMatches(ClaimsParameters<?> p, String expected) {
return p.getRealm() != null && p.getRealm().equalsIgnoreCase(expected);
} Prevention
- Keep a single source of truth for realm names shared by realm parser and claims handlers.
- Log both realm values on startup to catch drift early.
- Test multi-realm flows with each registered realm.
When it happens
Trigger: The STS issues a token for a realm whose name differs from the realm string this claims handler was configured with (e.g. handlerRealm set to 'A' but the token request parses/defaults to realm 'B', or getRealm() returns null because no realm parser matched).
Common situations: Misconfigured cas.authn.ws-sts realm maps vs the handler's realm property; missing or misfiring RealmParser so parameters.getRealm() is null; renamed realms after a migration; case/whitespace differences if code paths bypass equalsIgnoreCase.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- No principal could be identified in the claim parameters…
- No claims are available to process
- Retrieved realm from CN of SAML assertion certificate
- JWT time claim is invalid
- JWT audience is invalid
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/9011f8b5938fa5fc.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-ws-sts-api/src/main/java/org/apereo/cas/support/claims/WrappingSecurityTokenServiceClaimsHandler.java:43
@Getter
@RequiredArgsConstructor
public class WrappingSecurityTokenServiceClaimsHandler implements ClaimsHandler, RealmSupport {
private final String handlerRealm;
private final String issuer;
@Override
public List<String> getSupportedClaimTypes() {
return WSFederationClaims.ALL_CLAIMS.stream()
.map(WSFederationClaims::getUri)
.collect(Collectors.toList());
}
@Override
public ProcessedClaimCollection retrieveClaimValues(final ClaimCollection claims, final ClaimsParameters parameters) {
if (parameters.getRealm() == null || !parameters.getRealm().equalsIgnoreCase(this.handlerRealm)) {
LOGGER.warn("Realm [{}] doesn't match with configured realm [{}]", parameters.getRealm(), this.handlerRealm);
return new ProcessedClaimCollection();
}
if (parameters.getPrincipal() == null) {
LOGGER.warn("No principal could be identified in the claim parameters request");
return new ProcessedClaimCollection();
}
if (claims == null || claims.isEmpty()) {
LOGGER.warn("No claims are available to process");
return new ProcessedClaimCollection();
}
val claimCollection = new ProcessedClaimCollection();
claims.stream().map(c -> createProcessedClaim(c, parameters)).forEach(claimCollection::add);
return claimCollection;
}
/**
* Create processed claim processed claim.
*View on GitHub (pinned to e7288fc434)