apache/cassandra · error · InvalidRequestException

%s doesn't exist

Error message

%s doesn't exist

What it means

LIST ROLES OF <grantee> throws InvalidRequestException when the named grantee role does not exist, but only on the path where the caller has root-level SELECT/DESCRIBE permission on 'all roles'. Non-privileged users get the (nonexistent) empty view via the other branch instead.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/ListRolesStatement.java:104

    public void authorize(ClientState state) throws InvalidRequestException
    {
        // Authorization is enforced in execute(): a caller without DESCRIBE on the root roles
        // resource may only view roles granted to them, and is rejected with UnauthorizedException
        // before any existence check is reached.
    }

    public ResultMessage execute(ClientState state) throws RequestValidationException, RequestExecutionException
    {
        // If the executing user has DESCRIBE permission on the root roles resource, let them list any and all roles
        boolean hasRootLevelSelect = DatabaseDescriptor.getAuthorizer()
                                                       .authorize(state.getUser(), RoleResource.root())
                                                       .contains(Permission.DESCRIBE);
        if (hasRootLevelSelect)
        {
            if (grantee == null)
                return resultMessage(DatabaseDescriptor.getRoleManager().getAllRoles());
            if (!DatabaseDescriptor.getRoleManager().isExistingRole(grantee))
                throw new InvalidRequestException(String.format("%s doesn't exist", grantee));
            return resultMessage(DatabaseDescriptor.getRoleManager().getRoles(grantee, recursive));
        }
        else
        {
            RoleResource currentUser = RoleResource.role(state.getUser().getName());
            if (grantee == null)
                return resultMessage(DatabaseDescriptor.getRoleManager().getRoles(currentUser, recursive));
            if (DatabaseDescriptor.getRoleManager().getRoles(currentUser, true).contains(grantee))
                return resultMessage(DatabaseDescriptor.getRoleManager().getRoles(grantee, recursive));
            else
                throw new UnauthorizedException(String.format("You are not authorized to view roles granted to %s ", grantee.getRoleName()));
        }
    }

    private ResultMessage resultMessage(Set<RoleResource> roles)
    {
        if (roles.isEmpty())
            return new ResultMessage.Void();

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Verify existing roles with LIST ROLES; and fix the name
  2. Create the missing role if expected
  3. Omit OF <grantee> to list all roles you can see

Example fix

// before
LIST ROLES OF temp_contractor; // already dropped
// after
LIST ROLES; // confirm existing roles first
Defensive patterns

Strategy: validation

Validate before calling

boolean exists = DatabaseDescriptor.getRoleManager().isExistingRole(RoleResource.role(grantee));
if (!exists) throw new IllegalArgumentException(grantee + " doesn't exist");

Try / catch

try { session.execute("LIST ROLES OF " + grantee); } catch (InvalidRequestException e) { if (e.getMessage().endsWith("doesn't exist")) log.warn("skip unknown role {}", grantee); else throw e; }

Prevention

When it happens

Trigger: A user with DESCRIBE permission on RoleResource.root() executes LIST ROLES OF <role> (optionally with RECURSIVE) where isExistingRole(grantee) is false.

Common situations: Operators auditing roles after offboarding/cleanup; typos in role names; scripts run against a cluster where the role was never created.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/3a71a445f626a6ee. Report an issue: GitHub.