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

  1. Run nodetool describecluster / check schema versions and resolve schema disagreement across nodes.
  2. 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.
  3. Restore schema from the same backup generation as the data, or run a repair/scrub after aligning schemas.
  4. 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

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


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