apache/cassandra · critical · java.lang.RuntimeException
Unknown column <name> during deserialization
Error message
Unknown column <name> during deserialization
What it means
Thrown by Columns.Serializer.deserialize when a serialized column name cannot be resolved against the table metadata. The serializer first tries the regular columns and then, as a lenient fallback, the dropped-column registry; if neither knows the name, the on-disk data references a column this node's schema cannot account for. This indicates schema metadata and SSTable data are out of sync.
Source
Thrown at src/java/org/apache/cassandra/db/Columns.java:513
public Columns deserialize(DataInputPlus in, TableMetadata metadata) throws IOException
{
int length = in.readUnsignedVInt32();
try (BTree.FastBuilder<ColumnMetadata> builder = BTree.fastBuilder())
{
for (int i = 0; i < length; i++)
{
ByteBuffer name = ByteBufferUtil.readWithVIntLength(in);
ColumnMetadata column = metadata.getColumn(name);
if (column == null)
{
// If we don't find the definition, it could be we have data for a dropped column, and we shouldn't
// fail deserialization because of that. So we grab a "fake" ColumnMetadata that ensure proper
// deserialization. The column will be ignore later on anyway.
column = metadata.getDroppedColumn(name);
if (column == null)
throw new RuntimeException("Unknown column " + UTF8Type.instance.getString(name) + " during deserialization");
}
builder.add(column);
}
return new Columns(builder.build());
}
}
/**
* If both ends have a pre-shared superset of the columns we are serializing, we can send them much
* more efficiently. Both ends must provide the identically same set of columns.
*/
public void serializeSubset(Collection<ColumnMetadata> columns, Columns superset, DataOutputPlus out) throws IOException
{
/**
* We weight this towards small sets, and sets where the majority of items are present, since
* we expect this to mostly be used for serializing result sets.
*
* For supersets with fewer than 64 columns, we encode a bitmap of *missing* columns,View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Run nodetool describecluster / check schema versions and resolve schema disagreement across nodes.
- Verify the column was dropped correctly (ALTER TABLE ... DROP) so it is registered in dropped_columns; re-add then drop the column if the history was lost.
- Restore schema from the same backup generation as the data, or run a repair/scrub after aligning schemas.
- If unrecoverable, remove or rewrite the affected SSTables (nodetool scrub / garbage collect) after backing them up.
Example fix
// before: reading data written under an older schema that lost its dropped_columns entry // cqlsh> DESCRIBE TABLE t; -- column 'foo' missing, no dropped_columns record // after // cqlsh> ALTER TABLE t ADD foo int; -- recreate at the original type // cqlsh> ALTER TABLE t DROP foo; -- register it in dropped_columns, then retry the read
Defensive patterns
Strategy: try-catch
Validate before calling
// Compare schema versions before reads after schema changes
Metadata metadata = session.getMetadata().getKeyspaces().get(keyspace);
if (metadata == null || !metadata.getTables().containsKey(table))
throw new IllegalStateException("schema mismatch for " + keyspace + "." + table); Try / catch
try { resultSet = session.execute(read); }
catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Unknown column")) {
// schema/data mismatch: force schema refresh or repair
cluster.refreshSchema();
} else throw e;
} Prevention
- Always ALTER TABLE ... DROP columns properly (never delete schema rows manually) so dropped_columns history is preserved.
- Check nodetool describecluster schema agreement after schema changes before resuming traffic.
- Flush and repair after schema migrations on all nodes.
- Restore schema and data backups from the same generation.
When it happens
Trigger: Reading (deserializing) a partition whose stored cell column identifier is not present in TableMetadata and has no DroppedColumn entry; typically during a read/compaction/streaming after an altered schema.
Common situations: Schema restored from a snapshot taken after the data was written; dropped column without proper flush/GC of old data on another node; schema disagreement during rolling upgrades; manually edited system_schema tables.
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
- Corrupt flags value for clustering prefix (isStatic flag set
- Clustering block upper bits (those not associated with keys)
- Invalid Columns subset bytes; too many bits set: ${encoded}
- Invalid large Columns subset: missing count ${encoded} of ${
- category %s not found in %s
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/e17b397fbd8447d3.
Report an issue: GitHub.