apache/cassandra · error · AlreadyExistsException

${reason}

Error message

${reason}

What it means

Schema.submit distributes a schema transformation through the cluster and maps the resulting commit failure code to a client-facing exception. When the coordinator reports ALREADY_EXISTS, the reason string is rethrown as an AlreadyExistsException indicating the keyspace/table being created already exists.

Solutions

  1. Use IF NOT EXISTS in the CREATE statement (e.g. CREATE KEYSPACE IF NOT EXISTS ...).
  2. Check existing schema with DESCRIBE or system_schema queries before issuing the create.
  3. Catch AlreadyExistsException and treat it as success if the existing definition matches what you need.

Example fix

// before
session.execute("CREATE KEYSPACE ks WITH replication = {'class':'SimpleStrategy','replication_factor':1}");
// after
session.execute("CREATE KEYSPACE IF NOT EXISTS ks WITH replication = {'class':'SimpleStrategy','replication_factor':1}");
Defensive patterns

Strategy: try-catch

Validate before calling

Row r = session.execute("SELECT keyspace_name FROM system_schema.keyspaces WHERE keyspace_name = ?", ks).one();
boolean exists = r != null;

Try / catch

try { session.execute(createStmt); }
catch (AlreadyExistsException e) { logger.info("Keyspace/table already exists, continuing"); }

Prevention

When it happens

Trigger: Executing CREATE KEYSPACE / CREATE TABLE / CREATE TYPE via Schema.submit whose name already exists in the current schema, or a raced concurrent create from another coordinator that committed first.

Common situations: Idempotent migration scripts re-run without IF NOT EXISTS; two clients concurrently creating the same schema object; application startup code that unconditionally creates keyspaces.

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

Appendix: source

Thrown at src/java/org/apache/cassandra/schema/Schema.java:313

    {
        return getTableMetadata(descriptor.ksname, descriptor.cfname);
    }

    @Override
    public ClusterMetadata submit(SchemaTransformation transformation)
    {
        logger.debug("Submitting schema transformation {}", transformation);

        // result of this execution can be either a complete failure/timeout, or a success, but together with a log of
        // operations that have to be applied before we can do anything
        return ClusterMetadataService.instance()
                                     .commit(new AlterSchema(transformation),
                                             (metadata) -> metadata,
                                             (code, reason) -> {
                                                 switch (code)
                                                 {
                                                     case ALREADY_EXISTS:
                                                         throw new AlreadyExistsException(reason);
                                                     case CONFIG_ERROR:
                                                         throw new ConfigurationException(reason);
                                                     case SYNTAX_ERROR:
                                                         throw new SyntaxException(reason);
                                                     case UNAUTHORIZED:
                                                         throw new UnauthorizedException(reason);
                                                     default:
                                                         throw new InvalidRequestException(reason);
                                                 }
                                             });
    }

    // We need to lazy-initialize schema for test purposes: since column families are initialized
    // eagerly, if local schema initialization is attempted before commit log instance is started,
    // cf initialization will fail to grab a current commit log position.
    //
    // This could be further improved by providing a special Schema instance for tests, or
    // using supplier with precomputed value for regular code path, and lazy variable for tests.

View on GitHub (pinned to 88fd0f6a0e)