apereo/cas · error · InvalidResourceSetException

Resource set registration is missing scopes

Error message

Resource set registration is missing scopes

What it means

UMA resource sets must declare at least one scope. ResourceSet.validate(profile) throws InvalidResourceSetException with HTTP 400 when the scopes collection is empty, since scopes are required for later permission/policy evaluation.

Solutions

  1. Add a non-empty scopes array to the resource-set registration payload
  2. Use the exact 'scopes' JSON field name the model expects
  3. Register/verify the scopes exist or are acceptable for the associated client
  4. Populate scopes via addScope() when constructing ResourceSet objects in code

Example fix

// before
{"name":"photos","clientId":"myClient","scopes":[]}
// after
{"name":"photos","clientId":"myClient","scopes":["read","write"]}
Defensive patterns

Strategy: validation

Validate before calling

if (resourceSet.getScopes() == null || resourceSet.getScopes().isEmpty()) {
  throw new IllegalArgumentException("At least one scope is required");
}

Type guard

boolean hasScopes(ResourceSet rs) { return rs.getScopes() != null && !rs.getScopes().isEmpty(); }

Try / catch

try { registerResourceSet(rs); } catch (InvalidResourceSetException e) { return ResponseEntity.badRequest().body(e.getMessage()); }

Prevention

When it happens

Trigger: POSTing a resource-set registration (or updating one) whose body has no scopes array, an empty scopes array, or scopes that failed to deserialize, then calling ResourceSet.validate.

Common situations: Client omits scopes believing they're optional; JSON key mismatch (scope singular vs scopes) causing an empty collection; programmatically built ResourceSet never had addScope called.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-oauth-uma-core/src/main/java/org/apereo/cas/uma/ticket/resource/ResourceSet.java:76

    private String clientId;
    
    @Column(columnDefinition = "json")
    @Type(JsonType.class)
    private Set<ResourceSetPolicy> policies = new HashSet<>();

    /**
     * Validate.
     *
     * @param profile the profile
     */
    @JsonIgnore
    public void validate(final UserProfile profile) {
        if (StringUtils.isBlank(getClientId())) {
            throw new InvalidResourceSetException(HttpStatus.BAD_REQUEST.value(), "Authentication request does contain a client id");
        }

        if (getScopes().isEmpty()) {
            throw new InvalidResourceSetException(HttpStatus.BAD_REQUEST.value(), "Resource set registration is missing scopes");
        }

        if (!getOwner().equals(profile.getId())) {
            throw new InvalidResourceSetException(HttpStatus.FORBIDDEN.value(), "Resource-set owner does not match the authenticated profile");
        }
    }
}

View on GitHub (pinned to e7288fc434)