apache/cassandra · error · IllegalStateException

Cannot serialize RedundantStatus larger than 0xFFFF. Require

Error message

Cannot serialize RedundantStatus larger than 0xFFFF. Requires serialization changes.

What it means

CommandStoreSerializers.cast packs a RedundantStatus value into 16 bits for the wire format. If the long value exceeds 0xFFFF (65535) it cannot fit in a short, so serialize throws IllegalStateException: supporting larger values would require a wire-format change. This is a hard limit of the current Accord RedundantBefore serialization scheme.

Source

Thrown at src/java/org/apache/cassandra/service/accord/serializers/CommandStoreSerializers.java:278

            if (b.endEpoch == Long.MAX_VALUE) out.writeUnsignedVInt(0L);
            else out.writeUnsignedVInt(1 + b.endEpoch - b.startEpoch);
            serializeNullable(b.staleUntilAtLeast, out);
            out.writeUnsignedVInt32(b.bounds.length);
            for (TxnId bound : b.bounds)
            {
                CommandSerializers.txnId.serialize(bound, out);
            }
            for (int i = 0 ; i < b.bounds.length ; ++i)
            {
                out.writeShort(cast(b.status(i * 2)));
                out.writeShort(cast(b.status(i * 2 + 1)));
            }
        }

        private short cast(long v)
        {
            if ((v & ~0xFFFF) != 0)
                throw new IllegalStateException("Cannot serialize RedundantStatus larger than 0xFFFF. Requires serialization changes.");
            return (short)v;
        }

        @Override
        public RedundantBefore.Bounds deserialize(DataInputPlus in) throws IOException
        {
            if (in.readByte() == 0)
                return null;

            Range range = KeySerializers.range.deserialize(in);
            long startEpoch = in.readUnsignedVInt();
            long endEpoch = in.readUnsignedVInt();
            if (endEpoch == 0) endEpoch = Long.MAX_VALUE;
            else endEpoch = endEpoch - 1 + startEpoch;
            Timestamp staleUntilAtLeast = deserializeNullable(in);
            int count = in.readUnsignedVInt32();

            TxnId[] bounds = new TxnId[count];

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Check the value being cast (epoch/position) to confirm it really exceeds 0xFFFF; if it is unexpected, investigate counter growth/reset logic.
  2. For legitimately large values, extend the wire format to 4+ bytes for RedundantStatus, coordinating the change across the cluster.
  3. As a short-term mitigation, restart/reset epoch counters so values stay below 65535 until the serialization change ships.

Example fix

// before
if ((v & ~0xFFFF) != 0)
    throw new IllegalStateException("Cannot serialize RedundantStatus larger than 0xFFFF. Requires serialization changes.");
return (short)v;
// after (wire-format change)
in.putInt(v); out.writeInt(cast32(v));
private int cast32(long v) { if ((v & ~0xFFFFFFFFL) != 0) throw ...; return (int)v; }
Defensive patterns

Strategy: validation

Validate before calling

long v = status.get();
if ((v & ~0xFFFFL) != 0)
    throw new IllegalArgumentException("RedundantStatus value " + v + " exceeds 0xFFFF serialization limit");
serializer.serialize(status, out, version);

Try / catch

try {
    serializer.serialize(status, out, version);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("larger than 0xFFFF"))
        logger.error("RedundantStatus overflow; epoch/counter growth exceeded wire format", e);
    else throw e;
}

Prevention

When it happens

Trigger: serialize calls cast with a RedundantStatus/Bounds value > 65535, e.g. an epoch or position counter that grew beyond 16 bits before being written for RedundantBefore.

Common situations: Very long-running clusters where Accord epochs or command IDs grow large; tests that synthetically inflate epoch counters; a future format change raising the limit but writing to nodes on the old format.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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