apache/cassandra · warning
Role ' ' was not granted on
Error message
Role '%s' was not granted %s on %s
What it means
REVOKE of permissions that the role does not hold warns instead of failing. RevokePermissionsStatement.execute computes the actually-revoked subset and warns for each requested permission that was never granted (directly or via inheritance).
Solutions
- Run LIST ALL PERMISSIONS OF role_name to confirm the grant exists before revoking
- Make cleanup scripts tolerant of already-revoked state (treat the warning as success)
- Revoke the role membership instead if the permission comes from an inherited role
Example fix
// before
session.execute("REVOKE MODIFY ON ks.tbl FROM old_role"); // may never have been granted
// after
List<Row> perms = session.execute("LIST ALL PERMISSIONS OF old_role").all();
boolean has = perms.stream().anyMatch(p -> p.getString("permission").equals("MODIFY"));
if (has) session.execute("REVOKE MODIFY ON ks.tbl FROM old_role"); Defensive patterns
Strategy: validation
Validate before calling
boolean has = session.execute("LIST ALL PERMISSIONS OF " + role).all().stream()
.anyMatch(r -> r.getString("permission").equals(perm));
if (!has) { /* skip REVOKE, treat as no-op */ } Prevention
- Check grants before revoke in teardown scripts
- Remember inherited permissions cannot be revoked directly
- Treat this warning as success in cleanup jobs
When it happens
Trigger: Running `REVOKE permission ON resource FROM role` where the role lacks that permission; warning raised via ClientWarn when the revoked set is a strict subset of the requested permissions.
Common situations: Teardown/cleanup scripts revoking grants that were never applied; revoking permissions that were inherited, not directly granted; typos in permission names resolving to a valid-but-unheld permission.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Role ' ' was already granted on
- Aggregation query used on multiple partition keys (IN…
- Aggregation query used without partition key
- Altering permissions on builtin functions is not supported
- <dynamic warning, no literal in source: built by…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/b6c0b9041fb525ee.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/RevokePermissionsStatement.java:61
super(permissions, resource, grantee);
}
public ResultMessage execute(ClientState state) throws RequestValidationException, RequestExecutionException
{
IAuthorizer authorizer = DatabaseDescriptor.getAuthorizer();
Set<Permission> revoked = authorizer.revoke(state.getUser(), permissions, resource, grantee);
// We want to warn the client if all the specified permissions have not been revoked and the client did
// not specify ALL in the query.
if (!revoked.equals(permissions) && !permissions.equals(Permission.ALL))
{
String permissionsStr = permissions.stream()
.filter(permission -> !revoked.contains(permission))
.sorted(Permission::compareTo) // guarantee the order for testing
.map(Permission::name)
.collect(Collectors.joining(", "));
ClientWarn.instance.warn(String.format("Role '%s' was not granted %s on %s",
grantee.getRoleName(),
permissionsStr,
resource));
}
return null;
}
@Override
public String toString()
{
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
@Override
public AuditLogContext getAuditLogContext()
{
String keyspace = resource.hasParent() ? resource.getParent().getName() : resource.getName();View on GitHub (pinned to 88fd0f6a0e)