apache/cassandra · error · IOException

Unexpected node type: " + ident

Error message

Unexpected node type: " + ident

What it means

MerkleTree's on-heap node deserializer reads an IDENT byte to decide which node class (Inner or Leaf) to construct. Any other byte means the serialized tree is unreadable, so it throws IOException('Unexpected node type: ' + ident). This protects against version skew or corruption in MerkleTree streams exchanged during repair.

Source

Thrown at src/java/org/apache/cassandra/utils/MerkleTree.java:923

        @Override
        public long partitionsInRange()
        {
            return partitionsInRange;
        }

        static OnHeapNode deserialize(DataInputPlus in, IPartitioner p, int version) throws IOException
        {
            byte ident = in.readByte();

            switch (ident)
            {
                case Inner.IDENT:
                    return OnHeapInner.deserializeWithoutIdent(in, p, version);
                case Leaf.IDENT:
                    return OnHeapLeaf.deserializeWithoutIdent(in);
                default:
                    throw new IOException("Unexpected node type: " + ident);
            }
        }

        abstract int serializeOffHeap(ByteBuffer buffer, IPartitioner p) throws IOException;
    }

    static abstract class OffHeapNode implements Node
    {
        protected final ByteBuffer buffer;
        protected final int offset;

        OffHeapNode(ByteBuffer buffer, int offset)
        {
            this.buffer = buffer;
            this.offset = offset;
        }

        ByteBuffer buffer()

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Ensure all nodes doing repair run compatible Cassandra versions
  2. Regenerate the MerkleTrees (rerun repair validation) instead of reusing the serialized payload
  3. Hex-dump the stream to check for truncation or corruption upstream
  4. Confirm the deserializer version parameter matches the version used at serialization
Defensive patterns

Strategy: try-catch

Try / catch

try (DataInputStream in = new DataInputStream(stream)) {
    MerkleTree tree = MerkleTree.deserialize(in, version);
} catch (IOException e) {
    if (e.getMessage().startsWith("Unexpected node type")) {
        logger.error("MerkleTree stream corrupted or version-mismatched: {}", e.getMessage());
        // trigger re-validation / full repair instead of trusting the tree
    }
    throw e;
}

Prevention

When it happens

Trigger: Streaming/deserializing a MerkleTree whose bytes contain a node IDENT not matching Inner.IDENT or Leaf.IDENT — typically a tree serialized by a different Cassandra version or corrupted stream data.

Common situations: Repair between nodes on incompatible Cassandra versions; corrupted network payloads during anti-entropy sync; deserializing an old serialized tree dump with newer code.

Related errors


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