apache/cassandra · error · InvalidRequestException

Cannot re-add previously dropped column '%s' of kind %s, inc

Error message

Cannot re-add previously dropped column '%s' of kind %s, incompatible with previous kind %s

What it means

When re-adding a previously dropped column, its kind (REGULAR vs STATIC) must match the kind it had when dropped, because old rows' static cells would be misread as regular cells (or vice versa) if the kind flips. Cassandra compares the isStatic flag of the new column against the stored dropped ColumnMetadata and rejects a mismatch.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/AlterTableStatement.java:395

            }

            ColumnMetadata droppedColumn = table.getDroppedColumn(name.bytes);
            if (null != droppedColumn)
            {
                // After #8099, not safe to re-add columns of incompatible types - until *maybe* deser logic with dropped
                // columns is pushed deeper down the line. The latter would still be problematic in cases of schema races.
                if (!type.isSerializationCompatibleWith(droppedColumn.type))
                {
                    throw ire("Cannot add a column '%s' of type %s, incompatible with previously dropped column '%s' of type %s",
                              name,
                              type.asCQL3Type(),
                              name,
                              droppedColumn.type.asCQL3Type());
                }

                if (droppedColumn.isStatic() != isStatic)
                {
                    throw ire("Cannot re-add previously dropped column '%s' of kind %s, incompatible with previous kind %s",
                              name,
                              isStatic ? ColumnMetadata.Kind.STATIC : ColumnMetadata.Kind.REGULAR,
                              droppedColumn.kind);
                }

                // Cannot re-add a dropped counter column. See #7831.
                if (table.isCounter())
                    throw ire("Cannot re-add previously dropped counter column %s", name);
            }

            if (isStatic)
                tableBuilder.addStaticColumn(name, type, mask, columnConstraints);
            else
                tableBuilder.addRegularColumn(name, type, mask, columnConstraints);

            if (!isStatic)
            {
                for (ViewMetadata view : keyspace.views.forTable(table.id))

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Re-add the column with the same kind it had before dropping (omit STATIC if it was REGULAR; include STATIC if it was STATIC).
  2. If a kind change is required, use a new column name and migrate data with an INSERT/UPDATE copy, then drop the old column.
  3. Drop-and-recreate the table (after data migration) if the dropped-column history must be cleared to permit the new layout.
  4. Verify prior kind via system.dropped_columns (dropped_at/dropped metadata) before re-adding.

Example fix

// before
ALTER TABLE t DROP location;   -- was STATIC
ALTER TABLE t ADD location text;            -- kind mismatch (REGULAR)
// after
ALTER TABLE t ADD location text STATIC;     -- same kind as dropped
-- or use a new name: ALTER TABLE t ADD location2 text;
Defensive patterns

Strategy: validation

Validate before calling

// before re-adding, ensure the kind matches what was dropped
ColumnMetadata dropped = table.getDroppedColumn(ByteBufferUtil.bytes(colName));
if (dropped != null && dropped.isStatic() != isStaticRequested)
    throw new IllegalArgumentException("Kind mismatch: dropped column was " + dropped.kind + "; re-add with the same kind.");

Type guard

boolean kindMatches(TableMetadata t, String name, boolean isStatic) {
    ColumnMetadata d = t.getDroppedColumn(UTF8Type.instance.decompose(name));
    return d == null || d.isStatic() == isStatic;
}

Try / catch

try {
    session.execute(alterAdd);
} catch (InvalidQueryException e) {
    if (e.getMessage().contains("incompatible with previous kind"))
        throw new SchemaConflictException("Re-add the column with its original REGULAR/STATIC kind", e);
    throw e;
}

Prevention

When it happens

Trigger: ALTER TABLE t DROP col; then ALTER TABLE t ADD col <type> STATIC (or vice versa) on a table with clustering columns, where the dropped ColumnMetadata records the opposite kind.

Common situations: Toggling a column between regular and static after a drop; schema-migration tools converting a regular column to static by drop+add; developer experiments on tables whose dropped-column history still contains the old kind.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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