apache/cassandra · error · InvalidRequestException

already exists

Error message

%s already exists

What it means

A validation check in AddIdentityStatement.validate: when IF NOT EXISTS is not specified and the RoleManager already contains an identity with the same name, the statement fails with InvalidRequestException ('%s already exists' where %s is the identity). It protects against silently overwriting an existing identity.

Solutions

  1. Add IF NOT EXISTS: CREATE IDENTITY IF NOT EXISTS ...
  2. Drop the existing identity first (DROP IDENTITY) if replacement is intended
  3. Use a unique identity name

Example fix

// before
CREATE IDENTITY cert1 FOR 'app_role';
// after
CREATE IDENTITY IF NOT EXISTS cert1 FOR 'app_role';
Defensive patterns

Strategy: validation

Validate before calling

// check existence first, or use IF NOT EXISTS
ResultSet rs = session.execute("SELECT identity FROM system_auth.identities WHERE identity = ?", identityName);
boolean exists = !rs.all().isEmpty();
String cql = exists ? null : "CREATE IDENTITY " + (idempotent ? "IF NOT EXISTS " : "") + identityName + " ...";

Try / catch

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

Prevention

When it happens

Trigger: CREATE IDENTITY <name> ... (without IF NOT EXISTS) where isExistingIdentity(identity) is true — the identity was created previously by this or another operator.

Common situations: Re-running idempotent provisioning scripts; two operators creating the same named identity; CI pipelines replaying setup statements.

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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/AddIdentityStatement.java:72

    {
        checkPermission(state, Permission.CREATE, RoleResource.root());

        if (!state.getUser().isSuper() && DatabaseDescriptor.getRoleManager().isSuper(RoleResource.role(role)))
            throw new UnauthorizedException("Only superusers can bind identities to a role with superuser status");
    }

    @Override
    public void validate(ClientState state)
    {
        state.ensureNotAnonymous();

        if (!DatabaseDescriptor.getRoleManager().isExistingRole(RoleResource.role(role)))
        {
            throw new InvalidRequestException(String.format("Can not add identity for non-existent role '%s'", role));
        }

        if (!ifNotExists && DatabaseDescriptor.getRoleManager().isExistingIdentity(identity))
            throw new InvalidRequestException(String.format("%s already exists", identity));
    }

    @Override
    public AuditLogContext getAuditLogContext()
    {
        return new AuditLogContext(AuditLogEntryType.CREATE_IDENTITY);
    }

    @Override
    public ResultMessage execute(ClientState state) throws RequestExecutionException, RequestValidationException
    {
        if(!ifNotExists || !DatabaseDescriptor.getRoleManager().isExistingIdentity(identity))
        {
            DatabaseDescriptor.getRoleManager().addIdentity(identity, role);
        }
        return null;
    }
}

View on GitHub (pinned to 88fd0f6a0e)