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
- Verify existing roles with LIST ROLES; and fix the name
- Create the missing role if expected
- 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
- Run LIST ROLES first to confirm the grantee exists
- Keep role-name references in sync across environments
- Treat 'doesn't exist' as skippable in audit tooling
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
- %s doesn't exist
- %s doesn't support %s
- Only superusers can drop a role with superuser status
- Cannot DROP primary role for current login
- %s doesn't exist
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/3a71a445f626a6ee.
Report an issue: GitHub.