apereo/cas · error · STSException
Unknown realm:
Error message
Unknown realm:
What it means
UriRealmParser.parseRealm derives a realm from the WS-Trust request's `appliesTo` URI (e.g. http://schemas.xmlsoap.org/ws/2005/identity/org/apereo/cas) and looks it up in a configured realm map. If the parsed realm is blank or not present in the map, it throws STSException("Unknown realm: " + realm), refusing to issue a security token for an unconfigured realm.
Solutions
- Add the missing realm to the configured realm map (STS realm configuration) so the parsed appliesTo value matches a known key exactly.
- Log the appliesTo URI from the failing RST and compare it with configured realm keys for case/slash/spelling mismatches.
- Correct the RP/client to send the canonical AppliesTo URI that the CAS STS realm configuration expects.
- If realms are dynamic, supply a custom RealmParser bean whose map covers the additional realms instead of UriRealmParser's static map.
Example fix
// before: no entry for requested realm
map.put("https://cas.example.org/ws/sts/realm1", "encryption-key");
// after: add the realm the RP's appliesTo URI resolves to
map.put("https://cas.example.org/ws/sts/realm1", "encryption-key");
map.put("https://cas.example.org/ws/sts/realm2", "encryption-key-2"); Defensive patterns
Strategy: validation
Validate before calling
// Client-side pre-check before calling the STS:
String appliesTo = "https://cas.example.org/ws/sts/realm2";
if (!configuredRealmKeys.contains(appliesTo)) {
throw new IllegalArgumentException("AppliesTo realm not configured in CAS STS: " + appliesTo);
} Try / catch
// Server-side, wrapping STS token issuance:
try {
SecurityToken token = sts.issueToken(rst);
} catch (STSException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unknown realm")) {
throw new ConfigurationException("Realm not configured: " + e.getMessage());
}
throw e;
} Prevention
- Keep the realm map keys byte-identical (case, slashes, trailing segments) to the AppliesTo URIs RPs actually send.
- Add every new RP's realm to the STS configuration before onboarding it.
- Log parsed realm values at debug level to catch mismatches early.
When it happens
Trigger: A WS-Trust RST is submitted to the STS whose AppliesTo URI, after parsing via getRealm (segment at the adjusted token count), yields a realm string that is blank or absent from the `realmMap` configured on this realm parser.
Common situations: STS security configuration (cas.authn.ws-idp / STS realm settings) missing an entry for the RP's realm; RP sending a wrong or truncated appliesTo URI; CASConfigurationProperties realm map keys differing in case or trailing slash from the parsed value; token counts in the URI differing from the parser's expectations.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Keystore file, password or alias assigned to the realm are…
- No user can be accepted because none is defined
- Not all requested multifactor providers could be found…
- Cookie name is undefined
- List of candidate multifactor authentication providers is…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/1cae078605c5f3a4.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-ws-sts-api/src/main/java/org/apereo/cas/support/realm/UriRealmParser.java:36
@Slf4j
@RequiredArgsConstructor
public class UriRealmParser implements RealmParser {
private final Map<String, RealmProperties> realmMap;
@Override
public String parseRealm(final Map<String, Object> messageContext) throws STSException {
val url = (String) messageContext.get("org.apache.cxf.request.url");
val st = new StringTokenizer(url, "/");
var count = st.countTokens();
if (count <= 1) {
return null;
}
count--;
val realm = getRealm(st, count);
if (StringUtils.isBlank(realm) || !realmMap.containsKey(realm)) {
LOGGER.warn("Unknown realm: [{}]", realm);
throw new STSException("Unknown realm: " + realm);
}
LOGGER.debug("URI realm parsed: [{}]", realm);
return realm.trim();
}
private static String getRealm(final StringTokenizer st, final int count) {
var realm = StringUtils.EMPTY;
for (var i = 0; i < count; i++) {
realm = st.nextToken();
}
return realm.toUpperCase(Locale.ENGLISH);
}
}
View on GitHub (pinned to e7288fc434)