apache/cassandra · error · InvalidRequestException

Role %s doesn't exist

Error message

Role %s doesn't exist

What it means

PermissionsManagementStatement.validate() (used by GRANT/REVOKE) verifies the grantee role exists via the configured RoleManager after ensuring the user is not anonymous. If the role name doesn't exist, this InvalidRequestException is thrown including the role name.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/PermissionsManagementStatement.java:54

{
    protected final Set<Permission> permissions;
    protected IResource resource;
    protected final RoleResource grantee;

    protected PermissionsManagementStatement(Set<Permission> permissions, IResource resource, RoleName grantee)
    {
        this.permissions = permissions;
        this.resource = resource;
        this.grantee = RoleResource.role(grantee.getName());
    }

    public void validate(ClientState state) throws RequestValidationException
    {
        // validate login here before authorize to avoid leaking user existence to anonymous users.
        state.ensureNotAnonymous();

        if (!DatabaseDescriptor.getRoleManager().isExistingRole(grantee))
            throw new InvalidRequestException(String.format("Role %s doesn't exist", grantee.getRoleName()));

        // if a keyspace is omitted when GRANT/REVOKE ON TABLE <table>, we need to correct the resource.
        // called both here and in authorize(), as in some cases we do not call the latter.
        resource = maybeCorrectResource(resource, state);

        if (!resource.exists())
            throw new InvalidRequestException(String.format("Resource %s doesn't exist", resource));
    }

    public void authorize(ClientState state) throws UnauthorizedException
    {
        // if a keyspace is omitted when GRANT/REVOKE ON TABLE <table>, we need to correct the resource.
        resource = maybeCorrectResource(resource, state);

        // check that the user has AUTHORIZE permission on the resource or its parents, otherwise reject GRANT/REVOKE.
        state.ensurePermission(Permission.AUTHORIZE, resource);

        // check that the user has [a single permission or all in case of ALL] on the resource or its parents.

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Verify the role name with LIST ROLES and correct the spelling.
  2. Create the missing role first (CREATE ROLE ...), then re-run the GRANT/REVOKE.
  3. Confirm you are connected to the intended cluster/environment where the role exists.

Example fix

-- before
GRANT SELECT ON keyspace ks TO alice; -- alice does not exist
-- after
CREATE ROLE alice WITH LOGIN = true;
GRANT SELECT ON KEYSPACE ks TO alice;
Defensive patterns

Strategy: validation

Validate before calling

// before granting, check role exists
Row r = session.execute("SELECT role FROM system_auth.roles WHERE role = ?", grantee).one();
if (r == null) throw new IllegalStateException("Role " + grantee + " does not exist");

Try / catch

try { session.execute(grant); } catch (InvalidRequestException e) { if (e.getMessage().contains("doesn't exist")) { /* create role or fix name */ } else throw e; }

Prevention

When it happens

Trigger: GRANT ... TO <role> or REVOKE ... FROM <role> where grantee.getRoleName() is not a role known to the role manager (e.g. IRoleManager.isExistingRole returns false).

Common situations: Typo in role name; role was dropped before the GRANT/REVOKE; client connected against the wrong cluster/environment where the role was never created.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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