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

  1. Run LIST ALL PERMISSIONS OF role_name to confirm the grant exists before revoking
  2. Make cleanup scripts tolerant of already-revoked state (treat the warning as success)
  3. 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

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


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)