apache/cassandra · warning

Role ' ' was already granted on

Error message

Role '%s' was already granted %s on %s

What it means

GRANT role/permissions on a resource where the grantee already holds (a superset of) the requested permissions produces this client warning instead of an error. The statement filters out already-granted permissions and warns about the redundant remainder.

Solutions

  1. Check existing grants with LIST ALL PERMISSIONS OF role_name before granting
  2. Make provisioning scripts idempotent (issue GRANT only when LIST GRANTS shows it missing)
  3. If redundant grants are expected, downgrade the warning handling on the client (setWarnings callback)

Example fix

// before
session.execute("GRANT SELECT ON ks.tbl TO app_role"); // run on every deploy
// after
Row r = session.execute("LIST ALL PERMISSIONS OF app_role").one();
if (r == null) session.execute("GRANT SELECT ON ks.tbl TO app_role");
Defensive patterns

Strategy: validation

Validate before calling

// before granting, check existing permissions
boolean granted = session.execute("LIST ALL PERMISSIONS OF " + role).all().stream()
    .anyMatch(r -> r.getString("permission").equals("SELECT") && r.getString("resource").contains(resource));
if (granted) { /* skip GRANT */ }

Prevention

When it happens

Trigger: Running `GRANT permission ON resource TO role` where the role already has the permission, directly or via inheritance; GrantPermissionsStatement.execute collects not-granted permissions and warns when the intersection is non-empty.

Common situations: Idempotent setup scripts re-running GRANT statements; automation re-applying grants; granting overlapping permissions to a role that inherits them from another role.

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/7fd2cdc157fc4f45. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/GrantPermissionsStatement.java:79

        }
    }

    public ResultMessage execute(ClientState state) throws RequestValidationException, RequestExecutionException
    {
        IAuthorizer authorizer = DatabaseDescriptor.getAuthorizer();
        Set<Permission> granted = authorizer.grant(state.getUser(), permissions, resource, grantee);

        // We want to warn the client if all the specified permissions have not been granted and the client did
        // not specify ALL in the query.
        if (!granted.equals(permissions) && !permissions.equals(Permission.ALL))
        {
            String permissionsStr = permissions.stream()
                                               .filter(permission -> !granted.contains(permission))
                                               .sorted(Permission::compareTo) // guarantee the order for testing
                                               .map(Permission::name)
                                               .collect(Collectors.joining(", "));

            ClientWarn.instance.warn(String.format("Role '%s' was already granted %s on %s",
                                                   grantee.getRoleName(),
                                                   permissionsStr,
                                                   resource));
        }

        return null;
    }

    @Override
    public AuditLogContext getAuditLogContext()
    {
        String keyspace = resource.hasParent() ? resource.getParent().getName() : resource.getName();
        return new AuditLogContext(AuditLogEntryType.GRANT, keyspace, resource.getName());
    }

}

View on GitHub (pinned to 88fd0f6a0e)