apache/cassandra · error · java.io.IOException

Invalid Columns subset bytes; too many bits set:<encoded>

Error message

Invalid Columns subset bytes; too many bits set:<encoded>

What it means

Thrown by Columns.Serializer.deserializeSubset when decoding a bitmap-encoded column subset: after consuming all known columns, leftover bits remain set in the encoded long. The bitmap encodes more present columns than the serialized subset actually contains, so the payload is corrupt or was written by an incompatible serialization version.

Source

Thrown at src/java/org/apache/cassandra/db/Columns.java:601

                return deserializeLargeSubset(in, superset, (int) encoded);
            }
            else
            {
                try (BTree.FastBuilder<ColumnMetadata> builder = BTree.fastBuilder())
                {
                    int firstComplexIdx = 0;
                    for (ColumnMetadata column : superset)
                    {
                        if ((encoded & 1) == 0)
                        {
                            builder.add(column);
                            if (column.isSimple())
                                ++firstComplexIdx;
                        }
                        encoded >>>= 1;
                    }
                    if (encoded != 0)
                        throw new IOException("Invalid Columns subset bytes; too many bits set:" + Long.toBinaryString(encoded));
                    return new Columns(builder.build(), firstComplexIdx);
                }
            }
        }

        // encodes a 1 bit for every *missing* column, on the assumption presence is more common,
        // and because this is consistent with encoding 0 to represent all present
        private static long encodeBitmap(Collection<ColumnMetadata> columns, Columns superset, int supersetCount)
        {
            long bitmap = 0L;
            BTreeSearchIterator<ColumnMetadata, ColumnMetadata> iter = superset.iterator();
            // the index we would encounter next if all columns are present
            int expectIndex = 0;
            for (ColumnMetadata column : columns)
            {
                if (iter.next(column) == null)
                    throw new IllegalStateException(columns + " is not a subset of " + superset);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Identify and repair the affected SSTables (nodetool scrub) and run a repair to restore correct data from replicas.
  2. Verify all nodes run a compatible Cassandra version before/while upgrading; finish rolling upgrades consistently.
  3. Check disk health (SMART, filesystem errors) on the node reporting the error.
  4. If it reproduces deterministically, capture the payload and file a bug with the Cassandra project.
Defensive patterns

Strategy: retry

Try / catch

catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().contains("Invalid Columns subset bytes")) {
        // corrupt payload: fail over to another replica / trigger repair
        retryOnOtherReplica();
        scheduleRepair();
    } else throw e;
}

Prevention

When it happens

Trigger: Deserializing a SerializedMarker/subset payload where the 64-bit presence bitmap has bits set beyond the columns consumed; usually on-disk or inter-node payload corruption or a version mismatch between writer and reader.

Common situations: Bit-flip disk corruption; reading a data file or hinted payload produced by a different Cassandra version with a changed Columns encoding; restoring partial/mixed SSTables.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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