apache/cassandra · error · InvalidRequestException

%s doesn't exist

Error message

%s doesn't exist

What it means

Cassandra throws InvalidRequestException when DROP ROLE targets a role that does not exist in the RoleManager and IF EXISTS was not specified. The check is done in validate() with ensureNotAnonymous so anonymous users cannot probe role existence. With IF EXISTS the statement silently no-ops instead.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/DropRoleStatement.java:67

    public void authorize(ClientState state) throws UnauthorizedException
    {
        super.checkPermission(state, Permission.DROP, role);

        // We only check superuser status for existing roles to avoid
        // caching info about roles which don't exist (CASSANDRA-9189)
        if (DatabaseDescriptor.getRoleManager().isExistingRole(role)
            && Roles.hasSuperuserStatus(role)
            && !state.getUser().isSuper())
            throw new UnauthorizedException("Only superusers can drop a role with superuser status");
    }

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

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

        AuthenticatedUser user = state.getUser();
        if (user != null && user.getName().equals(role.getRoleName()))
            throw new InvalidRequestException("Cannot DROP primary role for current login");
    }

    public ResultMessage execute(ClientState state) throws RequestValidationException, RequestExecutionException
    {
        // not rejected in validate()
        if (ifExists && !DatabaseDescriptor.getRoleManager().isExistingRole(role))
            return null;

        // clean up grants and permissions of/on the dropped role.
        DatabaseDescriptor.getRoleManager().dropRole(state.getUser(), role);
        DatabaseDescriptor.getAuthorizer().revokeAllFrom(role);
        DatabaseDescriptor.getAuthorizer().revokeAllOn(role);
        DatabaseDescriptor.getNetworkAuthorizer().drop(role);
        DatabaseDescriptor.getCIDRAuthorizer().dropCidrPermissionsForRole(role);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Use DROP ROLE IF EXISTS <name> to make the statement idempotent
  2. Verify the role exists: LIST ROLES; or query system_auth.roles
  3. Correct the role name spelling/case in the statement
  4. Create the role first with CREATE ROLE if it should exist

Example fix

// before
DROP ROLE app_user; // InvalidRequestException if missing
// after
DROP ROLE IF EXISTS app_user;
Defensive patterns

Strategy: validation

Validate before calling

boolean exists = DatabaseDescriptor.getRoleManager().isExistingRole(RoleResource.role(name));
if (!exists && !ifExists) throw new IllegalArgumentException(name + " doesn't exist");

Try / catch

try { session.execute("DROP ROLE " + name); } catch (InvalidRequestException e) { if (e.getMessage().endsWith("doesn't exist")) log.info("already gone: {}", name); else throw e; }

Prevention

When it happens

Trigger: Executing DROP ROLE <name> (without IF EXISTS) where DatabaseDescriptor.getRoleManager().isExistingRole(role) is false — the role was never created, was already dropped, or is spelled differently (case/whitespace).

Common situations: Typos in role names; role dropped by another operator concurrently; migrations re-running DROP statements; environments (dev vs prod) where the role was never provisioned.

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


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