apache/cassandra · error · IOException

Corrupted input: expected byte 1 or 2, received " + b

Error message

Corrupted input: expected byte 1 or 2, received " + b

What it means

Seekable.serializer.deserialize reads one tag byte: 0 decodes a PartitionKey, 1 decodes a TokenRange. Any other byte throws IOException with the received value. The message text 'expected byte 1 or 2' is stale — the handled cases are actually 0 and 1. This error means the stream does not contain a valid serialized Seekable.

Source

Thrown at src/java/org/apache/cassandra/service/accord/serializers/KeySerializers.java:534

                default: throw new AssertionError();
                case Key:
                    out.writeByte(0);
                    PartitionKey.serializer.serialize((PartitionKey) seekable, out);
                    break;
                case Range:
                    out.writeByte(1);
                    TokenRange.serializer.serialize((TokenRange) seekable, out);
                    break;
            }
        }

        @Override
        public Seekable deserialize(DataInputPlus in) throws IOException
        {
            byte b = in.readByte();
            switch (b)
            {
                default: throw new IOException("Corrupted input: expected byte 1 or 2, received " + b);
                case 0: return PartitionKey.serializer.deserialize(in);
                case 1: return TokenRange.serializer.deserialize(in);
            }
        }

        @Override
        public void skip(DataInputPlus in) throws IOException
        {
            byte b = in.readByte();
            switch (b)
            {
                default: throw new IOException("Corrupted input: expected byte 1 or 2, received " + b);
                case 0: PartitionKey.serializer.skip(in); break;
                case 1: TokenRange.serializer.skip(in); break;
            }
        }

        @Override

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Confirm all nodes run compatible versions so the Seekable tag encoding matches.
  2. Log the received byte; note valid values are 0 (PartitionKey) and 1 (TokenRange) despite the message text.
  3. Check the connection for earlier deserialization errors that may have shifted the read position; reset if found.
  4. Fix the message string to say 'expected byte 0 or 1' for accurate debugging.

Example fix

// before
default: throw new IOException("Corrupted input: expected byte 1 or 2, received " + b);
// after
default: throw new IOException("Corrupted input: expected byte 0 or 1, received " + b);
Defensive patterns

Strategy: try-catch

Try / catch

try {
    Seekable s = Seekable.serializer.deserialize(in, version);
} catch (IOException e) {
    if (e.getMessage().startsWith("Corrupted input")) {
        logger.warn("Corrupt Seekable tag byte; dropping message", e);
    } else throw e;
}

Prevention

When it happens

Trigger: deserialize(DataInputPlus) reads a tag byte other than 0 or 1 when decoding a Seekable, e.g. inside Accord transaction/command deserialization.

Common situations: Corrupted or truncated network payloads; encoder/decoder version skew in a rolling upgrade; stream misaligned by a previous parse failure; test fixtures with wrong tag bytes.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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