apereo/cas · error

No groups could be found for

Error message

No groups could be found for [{}]

What it means

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'.

Solutions

  1. Verify the principal id format matches the Grouper subject identifier (check subject source and searchSubject attribute).
  2. Test the same subject id against the Grouper WS directly to confirm whether memberships exist.
  3. If users legitimately have no groups, adjust the access strategy (required attributes/groups) to not require Grouper membership.
  4. Check upstream logs for the Grouper WS warning (error 480) to rule out a connectivity/credential failure masquerading as empty results.

Example fix

// before
val accessStrategy = new GrouperRegisteredServiceAccessStrategy("uid={0}");
// after — ensure the principal attribute used matches the Grouper subject id
val accessStrategy = new GrouperRegisteredServiceAccessStrategy("employeeNumber");
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on the access strategy, confirm the subject resolves in Grouper
var results = facade.fetchGroupsFor(principalId);
if (results == null || results.length == 0) {
    logger.warn("Principal {} not resolvable in Grouper; access strategy will deny", principalId);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/fce5027dd9114d9a. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-grouper-core/src/main/java/org/apereo/cas/grouper/services/GrouperRegisteredServiceAccessStrategy.java:59

    private GrouperGroupField groupField = GrouperGroupField.NAME;

    /**
     * Collection of required attributes
     * for this service to proceed.
     */
    @JsonSetter(nulls = Nulls.AS_EMPTY)
    private Map<String, Set<String>> requiredAttributes = new HashMap<>();

    @JsonSetter(nulls = Nulls.AS_EMPTY)
    private Map<String, String> configProperties = new TreeMap<>();

    @Override
    public boolean authorizeRequest(final RegisteredServiceAccessStrategyRequest request) {
        val allAttributes = new HashMap<>(request.getAttributes());
        val results = fetchWsGetGroupsResults(request.getPrincipalId());
        if (results.isEmpty()) {
            LOGGER.warn("No groups could be found for [{}]", request.getPrincipalId());
            return false;
        }
        val grouperGroups = new ArrayList<>(results.size());
        results
            .stream()
            .filter(groupsResult -> groupsResult.getWsGroups() != null && groupsResult.getWsGroups().length > 0)
            .map(wsGetGroupsResult -> Arrays.stream(wsGetGroupsResult.getWsGroups()).collect(Collectors.toList()))
            .flatMap(List::stream)
            .forEach(group -> grouperGroups.add(GrouperFacade.getGrouperGroupAttribute(this.groupField, group)));
        LOGGER.debug("Adding [{}] under attribute name [{}] to collection of attributes", grouperGroups, GROUPER_GROUPS_ATTRIBUTE_NAME);
        allAttributes.put(GROUPER_GROUPS_ATTRIBUTE_NAME, grouperGroups);

        return RegisteredServiceAccessStrategyEvaluator.builder()
            .requiredAttributes(this.requiredAttributes)
            .build()
            .apply(request.withAttributes(allAttributes));
    }

View on GitHub (pinned to e7288fc434)