{"record":{"id":"b87f3a4257666535","repo":"apache/cassandra","slug":"cannot-use-alter-table-on-a-table-that-is-being-dr","errorCode":null,"errorMessage":"Cannot use ALTER TABLE on a table that is being dropped.","messagePattern":"Cannot use ALTER TABLE on a table that is being dropped\\.","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/AlterTableStatement.java","lineNumber":135,"sourceCode":"\n    public Keyspaces apply(ClusterMetadata metadata)\n    {\n        Keyspaces schema = metadata.schema.getKeyspaces();\n        KeyspaceMetadata keyspace = schema.getNullable(keyspaceName);\n\n        TableMetadata table = null == keyspace\n                            ? null\n                            : keyspace.getTableOrViewNullable(tableName);\n\n        if (null == table)\n        {\n            if (!ifExists)\n                throw ire(\"Table '%s.%s' doesn't exist\", keyspaceName, tableName);\n            return schema;\n        }\n\n        if (table.params.pendingDrop)\n            throw ire(\"Cannot use ALTER TABLE on a table that is being dropped.\");\n\n        if (table.isView())\n            throw ire(\"Cannot use ALTER TABLE on a materialized view; use ALTER MATERIALIZED VIEW instead\");\n\n        return schema.withAddedOrUpdated(apply(metadata.nextEpoch(), keyspace, table, metadata));\n    }\n\n    SchemaChange schemaChangeEvent(KeyspacesDiff diff)\n    {\n        return new SchemaChange(Change.UPDATED, Target.TABLE, keyspaceName, tableName);\n    }\n\n    public void authorize(ClientState client)\n    {\n        client.ensureTablePermission(keyspaceName, tableName, Permission.ALTER);\n    }\n\n    @Override","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/AlterTableStatement.java#L117-L153","documentation":"Thrown when ALTER TABLE is issued on a table whose TableMetadata.params.pendingDrop is true, i.e. the table is scheduled to be dropped (in-flight DROP in the Accord/transactional schema epoch pipeline). Cassandra refuses further DDL on a table already being torn down.","triggerScenarios":"ALTER TABLE statement applied while table.params.pendingDrop is true — typically when an ALTER races with a DROP TABLE of the same table, or a stale/queued schema statement lands after a drop was initiated","commonSituations":"Concurrent migration tooling issuing ALTER and DROP in parallel; a long-running ALTER statement submitted just before a DROP and retried after the drop begins; replayed DDL from a batch that also drops the table.","solutions":["Check whether the DROP was intended; if so, drop the ALTER from the migration","Re-issue the ALTER after the drop completes (it will then fail with 'doesn't exist', confirming ordering)","Serialize DDL: ensure only one coordinator/tool issues schema changes for the table at a time"],"exampleFix":"// before\n// ALTER and DROP queued concurrently\nsession.execute(\"DROP TABLE my_app.events\");\nsession.execute(\"ALTER TABLE my_app.events ADD extra text\"); // race\n// after\n// pick one: either keep the table and ALTER it, or drop it — not both\nsession.execute(\"ALTER TABLE my_app.events ADD extra text\");","handlingStrategy":"validation","validationCode":"// ensure no concurrent DROP is queued for the same table before ALTER\nboolean pendingDrop = /* from TableMetadata */ table.params.pendingDrop;\nif (pendingDrop) throw new IllegalStateException(\"Table is being dropped; skipping ALTER\");","typeGuard":null,"tryCatchPattern":"try {\n    session.execute(alter);\n} catch (InvalidRequestException e) {\n    if (e.getMessage().contains(\"being dropped\"))\n        log.warn(\"ALTER raced with DROP on {}; aborting migration step\", tableName);\n    else throw e;\n}","preventionTips":["Serialize all DDL through a single coordinator/lock","Do not batch ALTER and DROP for the same table in concurrent jobs","Order migrations strictly; avoid retrying an ALTER after a DROP of the same table"],"tags":["cassandra","cql","ddl","race-condition"],"backgroundTag":"invalid-state-transition","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}