apache/cassandra · error · InvalidRequestException

%s already exists

Error message

%s already exists

What it means

CreateRoleStatement.validate checks the role manager for an existing role and throws InvalidRequestException when the role already exists and IF NOT EXISTS was not specified. This pre-validation happens after ensureNotAnonymous so anonymous users cannot probe for role existence.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/CreateRoleStatement.java:97

        opts.validate();
        if (role.getRoleName().isEmpty())
            throw new InvalidRequestException("Role name can't be an empty string");

        if (dcPermissions != null)
        {
            dcPermissions.validate();
        }

        if (cidrPermissions != null)
        {
            cidrPermissions.validate();
        }

        // validate login here before authorize to avoid leaking role existence to anonymous users.
        state.ensureNotAnonymous();

        if (!ifNotExists && role != RoleResource.GENERATED_ROLE && DatabaseDescriptor.getRoleManager().isExistingRole(role))
            throw new InvalidRequestException(String.format("%s already exists", role.getRoleName()));
    }

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

        RoleResource roleResource;
        if (opts.isGeneratedName())
        {
            Map<String, Object> options = (Map<String, Object>) opts.getOptions().get(IRoleManager.Option.OPTIONS);
            String generatedName = Guardrails.roleNamePolicy.generate(state, options);
            if (generatedName != null)
                roleResource = RoleResource.role(generatedName);
            else
                throw new InvalidRequestException("You have to enable role_name_policy and its generator_class_name property " +
                                                  "in cassandra.yaml to be able to generate role names.");

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Use CREATE ROLE IF NOT EXISTS <name> ... to make the statement idempotent.
  2. Check existence first via LIST ROLES or a role-management tool before creating.
  3. Handle the existing role as a success case in provisioning scripts.

Example fix

// before
CREATE ROLE service_a WITH LOGIN = true AND PASSWORD = 'x';
// after
CREATE ROLE IF NOT EXISTS service_a WITH LOGIN = true AND PASSWORD = 'x';
Defensive patterns

Strategy: validation

Validate before calling

// make idempotent at the CQL level
const stmt = `CREATE ROLE IF NOT EXISTS ${name} WITH LOGIN = true`;

Try / catch

try { session.execute(cql); } catch (InvalidRequestException e) { if (e.getMessage().endsWith("already exists")) { /* treat as success for idempotent provisioning */ } else throw e; }

Prevention

When it happens

Trigger: Executing CREATE ROLE existing_name (without IF NOT EXISTS) when DatabaseDescriptor.getRoleManager().isExistingRole(role) returns true and the role is not the generated role.

Common situations: Idempotent provisioning scripts re-run against a cluster where the role was already created; concurrent setup jobs both creating the same role; CI reusing a persistent test cluster.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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