apache/cassandra · error · InvalidTypeException
Invalid 8-bits integer value, expecting 1 byte but got %d
Error message
Invalid 8-bits integer value, expecting 1 byte but got %d
What it means
Thrown by ByteCodec.deserializeNoBoxing when the ByteBuffer does not contain exactly 1 byte, the wire size of a CQL tinyint. Null/empty buffers return 0; any other length is invalid for an 8-bit signed integer.
Source
Thrown at src/java/org/apache/cassandra/cql3/functions/types/TypeCodec.java:1589
{
if (value == null) return "NULL";
return Byte.toString(value);
}
@Override
public ByteBuffer serializeNoBoxing(byte value, ProtocolVersion protocolVersion)
{
ByteBuffer bb = ByteBuffer.allocate(1);
bb.put(0, value);
return bb;
}
@Override
public byte deserializeNoBoxing(ByteBuffer bytes, ProtocolVersion protocolVersion)
{
if (bytes == null || bytes.remaining() == 0) return 0;
if (bytes.remaining() != 1)
throw new InvalidTypeException(
"Invalid 8-bits integer value, expecting 1 byte but got " + bytes.remaining());
return bytes.get(bytes.position());
}
}
/**
* This codec maps a CQL {@link DataType#smallint()} to a Java {@link Short}.
*/
private static class SmallIntCodec extends PrimitiveShortCodec
{
private static final SmallIntCodec instance = new SmallIntCodec();
private SmallIntCodec()
{
super(smallint());
}View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Check the column's declared CQL type and use the matching codec (ShortCodec for smallint, IntCodec for int).
- Log bytes.remaining() to infer the actual encoded width (2/4/8) and switch codecs accordingly.
- Use the row-level typed getters (getByte/getShort/getInt) so type selection is automatic.
- Migrate data to the intended type if producers and consumers disagree.
Example fix
// before
byte b = new ByteCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
// after
switch (bytes.remaining()) {
case 1: return new ByteCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
case 2: return (byte) new ShortCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
case 4: return (byte) new IntCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
default: throw new IllegalArgumentException("Unexpected width " + bytes.remaining());
} Defensive patterns
Strategy: validation
Validate before calling
if (bytes == null || bytes.remaining() == 0) return (byte) 0;
if (bytes.remaining() != 1)
throw new IllegalArgumentException("Expected 1 byte for tinyint, got " + bytes.remaining()); Type guard
boolean isByteSized(ByteBuffer b) { return b != null && (b.remaining() == 0 || b.remaining() == 1); } Try / catch
try { return codec.deserializeNoBoxing(bytes, protocolVersion); }
catch (InvalidTypeException e) {
log.warn("Tinyint deserialization failed: {} bytes", bytes.remaining());
return (byte) 0;
} Prevention
- Match codec width to column type (1/2/4/8 bytes).
- Use typed row getters rather than manual codecs.
- Watch for ALTER TABLE type changes across environments.
- Log remaining() to diagnose width mismatches.
When it happens
Trigger: Calling ByteCodec.deserializeNoBoxing(bytes, protocolVersion) with a ByteBuffer whose remaining() is 2, 4, 8, etc., typically deserializing a smallint/int/bigint column as tinyint.
Common situations: Column type changed from int to tinyint (or vice versa) in one environment but not another, manual UDT/collection element parsing with wrong codec, or importing legacy data.
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 16-bits integer value, expecting 2 bytes 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/f43c43588c9a0150.
Report an issue: GitHub.