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;
}
}
@OverrideView on GitHub (pinned to 88fd0f6a0e)
Solutions
- Confirm all nodes run compatible versions so the Seekable tag encoding matches.
- Log the received byte; note valid values are 0 (PartitionKey) and 1 (TokenRange) despite the message text.
- Check the connection for earlier deserialization errors that may have shifted the read position; reset if found.
- 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
- Remember valid Seekable tags are 0 and 1; the message text is stale.
- Keep serializers byte-compatible across rolling upgrades.
- Close/realign streams after any tag-byte failure.
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
- Corrupted input: expected byte 1, 2, 3, 4, 5 or 6; received
- Corrupted input: expected byte 1, 2, 3, 4 or 5; received
- Unsupported collection type:
- Unhandled CheckStatusReply kind:
- Cannot serialize RedundantStatus larger than 0xFFFF. Require
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/1d41165818c7054a.
Report an issue: GitHub.