{"record":{"id":"4c07861dc6e56398","repo":"apereo/cas","slug":"unknown-realm-4c0786","errorCode":null,"errorMessage":"Unknown realm: [{}]","messagePattern":"Unknown realm: \\[(.+?)\\]","errorType":"exception","errorClass":"STSException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-ws-sts-api/src/main/java/org/apereo/cas/support/realm/UriRealmParser.java","lineNumber":35,"sourceCode":" */\n@Slf4j\n@RequiredArgsConstructor\npublic class UriRealmParser implements RealmParser {\n\n    private final Map<String, RealmProperties> realmMap;\n\n    @Override\n    public String parseRealm(final Map<String, Object> messageContext) throws STSException {\n        val url = (String) messageContext.get(\"org.apache.cxf.request.url\");\n        val st = new StringTokenizer(url, \"/\");\n        var count = st.countTokens();\n        if (count <= 1) {\n            return null;\n        }\n        count--;\n        val realm = getRealm(st, count);\n        if (StringUtils.isBlank(realm) || !realmMap.containsKey(realm)) {\n            LOGGER.warn(\"Unknown realm: [{}]\", realm);\n            throw new STSException(\"Unknown realm: \" + realm);\n        }\n\n        LOGGER.debug(\"URI realm parsed: [{}]\", realm);\n        return realm.trim();\n    }\n\n    private static String getRealm(final StringTokenizer st, final int count) {\n        var realm = StringUtils.EMPTY;\n        for (var i = 0; i < count; i++) {\n            realm = st.nextToken();\n        }\n        return realm.toUpperCase(Locale.ENGLISH);\n    }\n}\n\n","sourceCodeStart":17,"sourceCodeEnd":52,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-ws-sts-api/src/main/java/org/apereo/cas/support/realm/UriRealmParser.java#L17-L52","documentation":"UriRealmParser.parseRealm extracts a realm from the request URI's last path segment and validates it against the configured realm map. If the extracted realm is blank or not a key in realmMap it logs this warning and throws STSException(\"Unknown realm: ...\"). Unlike the other entries here, this one does throw — the request fails.","triggerScenarios":"STS endpoint URL whose last segment (e.g. /ws/sts/MyRealm) is not present in the configured realmMap, or a URI with fewer than two segments so no realm can be parsed.","commonSituations":"Client pointed at the wrong STS realm path; realm renamed in config but clients still use the old URL; typo in the URL path; request sent to a non-realm STS endpoint.","solutions":["Add the requested realm name to the realmMap configuration (cas.authn.ws-sts.realm.*, UriRealmParser map) or fix the client URL to use an existing realm key.","Verify the exact realm string in the URL matches a map key (case-sensitive per containsKey).","Catch STSException on the client and inspect the message to learn which realm string was parsed.","If the endpoint should be realm-less, use a realm parser/endpoint configuration that returns null instead of parsing."],"exampleFix":"// before\nrealmMap = Map.of(\"RealmA\", propsA); // client calls /ws/sts/RealmB\n// after\nrealmMap = Map.of(\"RealmA\", propsA, \"RealmB\", propsB);","handlingStrategy":"try-catch","validationCode":"String realm = uri.substring(uri.lastIndexOf('/') + 1);\nif (!configuredRealms.containsKey(realm)) {\n    throw new IllegalArgumentException(\"Realm not configured: \" + realm);\n}","typeGuard":null,"tryCatchPattern":"try {\n    claims = claimsHandler.retrieveClaimValues(claims, params);\n} catch (STSException e) {\n    if (e.getMessage().startsWith(\"Unknown realm\")) {\n        // inspect e.getMessage() for the parsed realm, fix URL or config\n    }\n    throw e;\n}","preventionTips":["Generate STS endpoint URLs from the configured realm map, never hand-written.","Add a startup check that logs all configured realm keys.","Use integration tests that hit each realm path."],"tags":["sts","realm","uri","sts-exception"],"backgroundTag":"invalid-identifier","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}