{"record":{"id":"fce5027dd9114d9a","repo":"apereo/cas","slug":"no-groups-could-be-found-for","errorCode":null,"errorMessage":"No groups could be found for [{}]","messagePattern":"No groups could be found for \\[(.+?)\\]","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"support/cas-server-support-grouper-core/src/main/java/org/apereo/cas/grouper/services/GrouperRegisteredServiceAccessStrategy.java","lineNumber":59,"sourceCode":"\n    private GrouperGroupField groupField = GrouperGroupField.NAME;\n\n    /**\n     * Collection of required attributes\n     * for this service to proceed.\n     */\n    @JsonSetter(nulls = Nulls.AS_EMPTY)\n    private Map<String, Set<String>> requiredAttributes = new HashMap<>();\n\n    @JsonSetter(nulls = Nulls.AS_EMPTY)\n    private Map<String, String> configProperties = new TreeMap<>();\n\n    @Override\n    public boolean authorizeRequest(final RegisteredServiceAccessStrategyRequest request) {\n        val allAttributes = new HashMap<>(request.getAttributes());\n        val results = fetchWsGetGroupsResults(request.getPrincipalId());\n        if (results.isEmpty()) {\n            LOGGER.warn(\"No groups could be found for [{}]\", request.getPrincipalId());\n            return false;\n        }\n        val grouperGroups = new ArrayList<>(results.size());\n        results\n            .stream()\n            .filter(groupsResult -> groupsResult.getWsGroups() != null && groupsResult.getWsGroups().length > 0)\n            .map(wsGetGroupsResult -> Arrays.stream(wsGetGroupsResult.getWsGroups()).collect(Collectors.toList()))\n            .flatMap(List::stream)\n            .forEach(group -> grouperGroups.add(GrouperFacade.getGrouperGroupAttribute(this.groupField, group)));\n        LOGGER.debug(\"Adding [{}] under attribute name [{}] to collection of attributes\", grouperGroups, GROUPER_GROUPS_ATTRIBUTE_NAME);\n        allAttributes.put(GROUPER_GROUPS_ATTRIBUTE_NAME, grouperGroups);\n\n        return RegisteredServiceAccessStrategyEvaluator.builder()\n            .requiredAttributes(this.requiredAttributes)\n            .build()\n            .apply(request.withAttributes(allAttributes));\n    }\n","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-grouper-core/src/main/java/org/apereo/cas/grouper/services/GrouperRegisteredServiceAccessStrategy.java#L41-L77","documentation":"GrouperRegisteredServiceAccessStrategy.authorizeRequest denies access when the Grouper WS group lookup for the principal returns an empty result set. It logs 'No groups could be found for [principalId]' and returns false, blocking the service request. Note this treats an empty list as deny — it cannot distinguish 'user in no groups' from 'lookup failed'.","triggerScenarios":"authorizeRequest (via executeStrategy) when fetchWsGetGroupsResults(request.getPrincipalId()) returns an empty list — i.e. Grouper returned no WsGetGroupsResult for that principal, which happens if the principal id is unknown to Grouper or the upstream WS lookup failed silently.","commonSituations":"User authenticated via a different id format than the one stored in Grouper (e.g. email vs username); Grouper WS misconfigured so all lookups return empty; user genuinely has no group memberships but the access strategy requires group membership; Grouper WS outage producing empty results.","solutions":["Verify the principal id format matches the Grouper subject identifier (check subject source and searchSubject attribute).","Test the same subject id against the Grouper WS directly to confirm whether memberships exist.","If users legitimately have no groups, adjust the access strategy (required attributes/groups) to not require Grouper membership.","Check upstream logs for the Grouper WS warning (error 480) to rule out a connectivity/credential failure masquerading as empty results."],"exampleFix":"// before\nval accessStrategy = new GrouperRegisteredServiceAccessStrategy(\"uid={0}\");\n// after — ensure the principal attribute used matches the Grouper subject id\nval accessStrategy = new GrouperRegisteredServiceAccessStrategy(\"employeeNumber\");","handlingStrategy":"validation","validationCode":"// Before relying on the access strategy, confirm the subject resolves in Grouper\nvar results = facade.fetchGroupsFor(principalId);\nif (results == null || results.length == 0) {\n    logger.warn(\"Principal {} not resolvable in Grouper; access strategy will deny\", principalId);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Align the principal-id source attribute with the Grouper subject identifier (test with a real user).","Decide explicitly whether empty Grouper results should mean deny; document it in the service config.","Monitor for this warning in logs — it also fires during WS outages, not just genuine non-membership.","Seed test users into Grouper groups in CI to catch id-format mismatches early."],"tags":["grouper","authorization","access-control","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"}