apache/cassandra · error · InvalidRequestException
Column with name ' ' already exists
Error message
Column with name '%s' already exists
What it means
Thrown by ALTER TABLE ... ADD when a column with the given name already exists on the table and IF NOT EXISTS was not specified. The builder detects the collision via tableBuilder.getColumn(name) and rejects the statement instead of silently overwriting.
Solutions
- Use IF NOT EXISTS: ALTER TABLE ks.tbl ADD IF NOT EXISTS col type
- Verify existing column types match your intent: SELECT * FROM system_schema.columns WHERE keyspace_name=? AND table_name=?
- Make migrations idempotent or track applied migrations in a schema-version table
Example fix
// before
session.execute("ALTER TABLE my_app.events ADD description text");
// after
session.execute("ALTER TABLE my_app.events ADD IF NOT EXISTS description text"); Defensive patterns
Strategy: validation
Validate before calling
boolean exists = session.execute("SELECT column_name FROM system_schema.columns WHERE keyspace_name=? AND table_name=? AND column_name=?", ks, table, col).one() != null;
if (exists) log.info("Column already present; skipping ADD"); Try / catch
try {
session.execute(alter);
} catch (InvalidRequestException e) {
if (e.getMessage().contains("already exists"))
log.info("Column exists, continuing: {}", alter);
else throw e;
} Prevention
- Always use ADD IF NOT EXISTS in migrations
- Keep a schema-version/migration ledger so steps run once
- Compare intended vs existing column types when a name collides
When it happens
Trigger: 'ALTER TABLE ks.tbl ADD col type' where a column of that name already exists and ifColumnNotExists is false; re-running migration scripts that add columns; adding a column that differs only by case in an unquoted statement
Common situations: Non-idempotent schema migration executed twice; drift between environments where the column already exists in one; ORMs/tools that re-emit ADD COLUMN on startup.
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
- ACCESS TO DATACENTERS operations not supported by…
- Altering column types is no longer supported
- Cannot add a counter column to Accord table
- Cannot add new column to a COMPACT STORAGE table
- Cannot drop a table when materialized views still depend on…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/91996316367c2ad0.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/AlterTableStatement.java:356
.withSwapped(viewsBuilder.build());
}
private void addColumn(KeyspaceMetadata keyspace,
TableMetadata table,
Column column,
boolean ifColumnNotExists,
TableMetadata.Builder tableBuilder,
Views.Builder viewsBuilder)
{
ColumnIdentifier name = column.name;
AbstractType<?> type = column.type.prepare(keyspaceName, keyspace.types).getType();
boolean isStatic = column.isStatic;
ColumnMask mask = column.mask == null ? null : column.mask.prepare(keyspaceName, tableName, name, type, keyspace.userFunctions);
ColumnConstraints columnConstraints = column.constraints == null ? ColumnConstraints.NO_OP : column.constraints.prepare(name);
if (null != tableBuilder.getColumn(name)) {
if (!ifColumnNotExists)
throw ire("Column with name '%s' already exists", name);
return;
}
if (type.isCounter() && (table.params.transactionalMode.accordIsEnabled || table.params.transactionalMigrationFrom.migratingFromAccord()))
throw ire(format(ACCORD_COUNTER_COLUMN_UNSUPPORTED, keyspaceName, tableName, table.params.transactionalMode, table.params.transactionalMigrationFrom));
if (table.isCompactTable())
throw ire("Cannot add new column to a COMPACT STORAGE table");
if (isStatic && table.clusteringColumns().isEmpty())
throw ire("Static columns are only useful (and thus allowed) if the table has at least one clustering column");
// check for nested non-frozen UDTs or collections in a non-frozen UDT
if (type.isUDT() && type.isMultiCell())
{
for (AbstractType<?> fieldType : ((UserType) type).fieldTypes())
{
if (fieldType.isMultiCell())View on GitHub (pinned to 88fd0f6a0e)