apache/cassandra · error · InvalidRequestException

Cannot re-add previously dropped counter column %s

Error message

Cannot re-add previously dropped counter column %s

What it means

In a counter table, a dropped counter column cannot be re-added under the same name (CASSANDRA-7831). Counter increments are timestamped deltas; after a drop, re-adding the same name would let stale/deleted counter deltas be re-applied, producing incorrect totals. Cassandra rejects this outright at ALTER TABLE time.

Source

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

                {
                    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))
                {
                    if (view.includeAllColumns)
                    {
                        ColumnMetadata viewColumn = ColumnMetadata.regularColumn(view.metadata, name.bytes, type, ColumnMetadata.NO_UNIQUE_ID)
                                                                  .withNewMask(mask)
                                                                  .withNewColumnConstraints(columnConstraints);
                        viewsBuilder.put(viewsBuilder.get(view.name()).withAddedRegularColumn(viewColumn));
                    }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Use a new column name for the counter: ALTER TABLE t ADD c2 counter; and read/write the new counter.
  2. Reset a counter in place with an UPDATE ... SET c = c - <value> rather than dropping/re-adding.
  3. Migrate to a new counter table (counters are stored per-cell in a dedicated table) if a clean layout is required.
  4. Recreate the table (with data migration for non-counter data is not possible for counters; write fresh counters) to clear the dropped-column record.

Example fix

// before
ALTER TABLE metrics DROP hits;
ALTER TABLE metrics ADD hits counter;   -- fails (CASSANDRA-7831)
// after
ALTER TABLE metrics ADD hits_v2 counter;
-- or reset in place before dropping: UPDATE metrics SET hits = hits - <current> WHERE key = ...;
Defensive patterns

Strategy: validation

Validate before calling

// guard: never drop+re-add a counter column name
ColumnMetadata dropped = table.getDroppedColumn(ByteBufferUtil.bytes(colName));
if (table.isCounter() && dropped != null && newType.isCounter())
    throw new IllegalArgumentException("Cannot re-add dropped counter column " + colName + "; use a new name.");

Type guard

boolean counterReAddAllowed(TableMetadata t, String name) {
    return !(t.isCounter() && t.getDroppedColumn(UTF8Type.instance.decompose(name)) != null);
}

Try / catch

try {
    session.execute("ALTER TABLE t ADD " + colName + " counter");
} catch (InvalidQueryException e) {
    if (e.getMessage().contains("previously dropped counter column"))
        throw new SchemaConflictException("Counter columns cannot be re-added after drop (CASSANDRA-7831); use a new column name", e);
    throw e;
}

Prevention

When it happens

Trigger: On a table created WITH COUNTERS (or containing counter columns), execute ALTER TABLE t DROP c; followed by ALTER TABLE t ADD c counter; — table.isCounter() is true and a dropped column with that name exists.

Common situations: Attempting to 'reset' a counter by dropping and re-adding the column; schema-sync tools replaying a drop+add history on counter tables; restoring an old schema script that drops and re-adds counter columns.

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