{"record":{"id":"ad1b7c7d47e54865","repo":"apache/cassandra","slug":"cannot-drop-primary-key-column-s","errorCode":null,"errorMessage":"Cannot drop PRIMARY KEY column %s","messagePattern":"Cannot drop PRIMARY KEY column (.+?)","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/AlterTableStatement.java","lineNumber":502,"sourceCode":"        }\n\n        @Override\n        public boolean compatibleWith(ClusterMetadata metadata)\n        {\n            return metadata.directory.commonSerializationVersion.isAtLeast(Version.V0);\n        }\n\n        private void dropColumn(KeyspaceMetadata keyspace, TableMetadata table, ColumnIdentifier column, boolean ifExists, TableMetadata.Builder builder)\n        {\n            ColumnMetadata currentColumn = table.getColumn(column);\n            if (null == currentColumn) {\n                if (!ifExists)\n                    throw ire(\"Column %s was not found in table '%s'\", column, table);\n                return;\n            }\n\n            if (currentColumn.isPrimaryKeyColumn())\n                throw ire(\"Cannot drop PRIMARY KEY column %s\", column);\n\n            /*\n             * Cannot allow dropping top-level columns of user defined types that aren't frozen because we cannot convert\n             * the type into an equivalent tuple: we only support frozen tuples currently. And as such we cannot persist\n             * the correct type in system_schema.dropped_columns.\n             */\n            if (currentColumn.type.isUDT() && currentColumn.type.isMultiCell())\n                throw ire(\"Cannot drop non-frozen column %s of user type %s\", column, currentColumn.type.asCQL3Type());\n\n            if (!table.indexes.isEmpty())\n                AlterTableStatement.validateIndexesForColumnModification(table, column, false);\n\n            if (!isEmpty(keyspace.views.forTable(table.id)))\n                throw ire(\"Cannot drop column %s on base table %s with materialized views\", currentColumn, table.name);\n\n            builder.removeRegularOrStaticColumn(column);\n            builder.recordColumnDrop(currentColumn, getTimestamp());\n        }","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/AlterTableStatement.java#L484-L520","documentation":"This InvalidRequestException is thrown when `ALTER TABLE ... DROP` targets a column that is part of the PRIMARY KEY (partition key or clustering column). Cassandra cannot drop primary key columns because they determine data distribution and clustering order; removing them would invalidate existing data layout on disk.","triggerScenarios":"Executing `ALTER TABLE ks.tbl DROP pk_column` where pk_column appears in the PRIMARY KEY definition (any partition key or clustering column), regardless of the column's other properties. IF EXISTS does not bypass this check — it only tolerates a missing column.","commonSituations":"Developers trying to evolve a schema to remove a bad clustering key; migrations generated for a different table version where the column was not yet part of the key; confusion between regular and primary columns after a table redesign.","solutions":["Accept that primary key columns cannot be dropped; create a new table with the desired primary key and migrate data (e.g. via a new table + INSERT ... SELECT or an ETL job).","If you only need to stop writing to the column, keep it but stop using it in application queries.","If the schema was wrong, drop and recreate the table (with data loss) after exporting any needed data.","Review the table's PRIMARY KEY with DESCRIBE TABLE before writing drop migrations to exclude key columns."],"exampleFix":"// before\nALTER TABLE events DROP day; -- day is a clustering column: fails\n// after\nCREATE TABLE events_v2 (... PRIMARY KEY ((id), ts));\nINSERT INTO events_v2 SELECT ... FROM events; -- then swap tables","handlingStrategy":"validation","validationCode":"// Pre-check that the column is not part of the primary key\nResultSet rs = session.execute(\n  \"SELECT kind, position FROM system_schema.columns WHERE keyspace_name=? AND table_name=? AND column_name=?\",\n  ks, table, column);\nRow r = rs.one();\nboolean isPk = r != null && !\"regular\".equals(r.getString(\"kind\"));\n// if isPk, do not attempt DROP; plan table recreation instead","typeGuard":null,"tryCatchPattern":"try {\n    session.execute(\"ALTER TABLE ks.tbl DROP \" + column);\n} catch (com.datastax.oss.driver.api.core.servererrors.InvalidQueryException e) {\n    if (e.getMessage().contains(\"Cannot drop PRIMARY KEY column\")) {\n        // fall back to new-table + data migration strategy\n    } else throw e;\n}","preventionTips":["Read the table's PRIMARY KEY (DESCRIBE TABLE) before writing drop migrations.","Never include key columns in generated drop scripts.","Filter out partition/clustering columns programmatically via system_schema.columns.kind.","Design schemas carefully up front; changing primary keys requires table recreation."],"tags":["cql","schema","primary-key","alter-table"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}