apache/cassandra · error · InvalidTypeException
Invalid 16-bits integer value, expecting 2 bytes but got %d
Error message
Invalid 16-bits integer value, expecting 2 bytes but got %d
What it means
Thrown by ShortCodec.deserializeNoBoxing when the ByteBuffer does not contain exactly 2 bytes, the wire size of a CQL smallint. Null/empty buffers return 0; any other length cannot be read as a 16-bit signed integer.
Source
Thrown at src/java/org/apache/cassandra/cql3/functions/types/TypeCodec.java:1645
{
if (value == null) return "NULL";
return Short.toString(value);
}
@Override
public ByteBuffer serializeNoBoxing(short value, ProtocolVersion protocolVersion)
{
ByteBuffer bb = ByteBuffer.allocate(2);
bb.putShort(0, value);
return bb;
}
@Override
public short deserializeNoBoxing(ByteBuffer bytes, ProtocolVersion protocolVersion)
{
if (bytes == null || bytes.remaining() == 0) return 0;
if (bytes.remaining() != 2)
throw new InvalidTypeException(
"Invalid 16-bits integer value, expecting 2 bytes but got " + bytes.remaining());
return bytes.getShort(bytes.position());
}
}
/**
* This codec maps a CQL {@link DataType#cint()} to a Java {@link Integer}.
*/
private static class IntCodec extends PrimitiveIntCodec
{
private static final IntCodec instance = new IntCodec();
private IntCodec()
{
super(DataType.cint());
}View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Confirm the column's CQL type (smallint = 2 bytes) and select the matching codec.
- Log bytes.remaining() on failure to identify the true encoded width and reroute to ByteCodec/IntCodec/LongCodec as appropriate.
- Prefer typed row getters (getShort/getInt) over manual codec invocation so the codec matches the declared type.
- Align schema between producer and consumer clusters, or add a migration for the column.
Example fix
// before
short s = new ShortCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
// after
int n = bytes.remaining();
if (n == 2)
short s = new ShortCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
else if (n == 4)
int i = new IntCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
else
throw new IllegalArgumentException("Unexpected smallint width: " + n); Defensive patterns
Strategy: validation
Validate before calling
if (bytes == null || bytes.remaining() == 0) return (short) 0;
if (bytes.remaining() != 2)
throw new IllegalArgumentException("Expected 2 bytes for smallint, got " + bytes.remaining()); Type guard
boolean isShortSized(ByteBuffer b) { return b != null && (b.remaining() == 0 || b.remaining() == 2); } Try / catch
try { return codec.deserializeNoBoxing(bytes, protocolVersion); }
catch (InvalidTypeException e) {
log.warn("Smallint deserialization failed: {} bytes", bytes.remaining());
return (short) 0;
} Prevention
- Select codec by column DataType, not assumption.
- Use row.getShort/getInt instead of manual deserialization.
- Keep schemas in sync across clusters.
- Log buffer length on deserialization failures.
When it happens
Trigger: Calling ShortCodec.deserializeNoBoxing(bytes, protocolVersion) with a ByteBuffer whose remaining() is 1, 4, or 8, typically when a tinyint/int/bigint payload is deserialized as smallint.
Common situations: Environment schema drift (column types altered in one cluster only), manual parsing of UDT or collection elements with the wrong codec, or replaying binary logs/legacy data with mixed widths.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Invalid 64-bits double value, expecting 8 bytes but got
- Invalid 32-bits float value, expecting 4 bytes but got
- Invalid bytes for inet value, got bytes
- Invalid 8-bits integer value, expecting 1 byte but got %d
- Not enough bytes to read size of %dth field %s
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/0ec8257d476f0bf0.
Report an issue: GitHub.