{"record":{"id":"43a1f037f2f7f4b9","repo":"apereo/cas","slug":"subject-id-could-not-be-located","errorCode":null,"errorMessage":"Subject id [{}] could not be located.","messagePattern":"Subject id \\[(.+?)\\] could not be located\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-grouper-core/src/main/java/org/apereo/cas/grouper/DefaultGrouperFacade.java","lineNumber":30,"sourceCode":"import lombok.val;\nimport org.apache.commons.lang3.StringUtils;\n\n/**\n * This is {@link DefaultGrouperFacade} that acts as a wrapper\n * in front of the grouper API.\n *\n * @author Misagh Moayyed\n * @since 5.1.0\n */\n@Slf4j\npublic class DefaultGrouperFacade implements GrouperFacade {\n\n    @Override\n    public Collection<WsGetGroupsResult> getGroupsForSubjectId(final String subjectId) {\n        try {\n            val results = fetchGroupsFor(subjectId);\n            if (results == null || results.length == 0) {\n                LOGGER.warn(\"Subject id [{}] could not be located.\", subjectId);\n                return new ArrayList<>();\n            }\n            LOGGER.debug(\"Found [{}] groups for [{}]\", results.length, subjectId);\n            return CollectionUtils.wrapList(results);\n        } catch (final Exception e) {\n            LOGGER.warn(\"Grouper WS did not respond successfully. Ensure your credentials are correct \"\n                + \", the url endpoint for Grouper WS is correctly configured and the subject [{}] exists in Grouper.\", subjectId, e);\n        }\n        return new ArrayList<>();\n    }\n\n    protected WsGetGroupsResult[] fetchGroupsFor(final String subjectId) {\n        val groupsClient = new GcGetGroups().addSubjectId(subjectId);\n        return groupsClient.execute().getResults();\n    }\n\n    @Override\n    public WsGetPermissionAssignmentsResults getPermissionAssignments(final GrouperPermissionAssignmentsQuery query) {","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-grouper-core/src/main/java/org/apereo/cas/grouper/DefaultGrouperFacade.java#L12-L48","documentation":"DefaultGrouperFacade.getGroupsForSubjectId() calls the Grouper web service via fetchGroupsFor(subjectId). If the WS returns null or an empty result array, the subject has no (or unknown) group membership; CAS logs this warning and returns an empty list. Exceptions (bad credentials, unreachable WS) are caught separately and also return an empty list.","triggerScenarios":"getGroupsForSubjectId called with a subjectId that does not exist in Grouper, uses the wrong subject source/identifier format (e.g. username vs ePPN vs internal id), or the WS query legitimately matches zero groups.","commonSituations":"Grouper subject source misconfiguration where CAS passes an identifier Grouper cannot resolve; users with no group assignments; typo'd subjectId passed from calling authorization code.","solutions":["Verify the subjectId value exists in Grouper and matches the configured subject source (subjectId vs subjectIdentifier)","Check the Grouper WS credentials/URL configured for the facade by querying a known-good subject","Confirm in the Grouper UI that the subject actually belongs to groups (zero groups is a valid empty result)","Inspect the caller's logic: authorization attributes derived from an empty list will deny access"],"exampleFix":"// before\ngrouperFacade.getGroupsForSubjectId(username); // may not resolve\n// after (use the identifier Grouper's source resolves)\ngrouperFacade.getGroupsForSubjectId(user.getAttributeValue(\"eppn\"));","handlingStrategy":"fallback","validationCode":"if (subjectId == null || subjectId.isBlank()) {\n    throw new IllegalArgumentException(\"subjectId required\");\n}","typeGuard":null,"tryCatchPattern":"var groups = grouperFacade.getGroupsForSubjectId(subjectId);\nif (groups.isEmpty()) {\n    LOGGER.debug(\"no grouper groups for {}; denying by default\", subjectId);\n}","preventionTips":["Use the identifier format Grouper's subject source resolves (e.g. ePPN)","Test the WS query with a known member before wiring authorization logic","Default to deny when the group list is empty"],"tags":["grouper","web-service","subject-not-found","empty-result"],"backgroundTag":"empty-result-set","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"}