apache/cassandra · error · InvalidTypeException
Invalid boolean value, expecting 1 byte but got
Error message
Invalid boolean value, expecting 1 byte but got
What it means
The boolean codec's deserializeNoBoxing() expects exactly 1 byte on the wire (any nonzero byte is true). A buffer whose remaining size differs from 1 means the bytes are not a CQL boolean, so the codec throws instead of guessing.
Source
Thrown at src/java/org/apache/cassandra/cql3/functions/types/TypeCodec.java:1279
@Override
public String format(Boolean value)
{
if (value == null) return "NULL";
return value ? "true" : "false";
}
@Override
public ByteBuffer serializeNoBoxing(boolean value, ProtocolVersion protocolVersion)
{
return value ? TRUE.duplicate() : FALSE.duplicate();
}
@Override
public boolean deserializeNoBoxing(ByteBuffer bytes, ProtocolVersion protocolVersion)
{
if (bytes == null || bytes.remaining() == 0) return false;
if (bytes.remaining() != 1)
throw new InvalidTypeException(
"Invalid boolean value, expecting 1 byte but got " + bytes.remaining());
return bytes.get(bytes.position()) != 0;
}
}
/**
* This codec maps a CQL {@link DataType#decimal()} to a Java {@link BigDecimal}.
*/
private static class DecimalCodec extends TypeCodec<BigDecimal>
{
private static final DecimalCodec instance = new DecimalCodec();
private DecimalCodec()
{
super(DataType.decimal(), BigDecimal.class);
}View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Encode booleans as exactly one byte: ByteBuffer.allocate(1).put((byte)(b ? 1 : 0)).
- Match the codec to the actual column type (tinyint codec for 1-byte signed ints, etc.).
- Refresh cached prepared statements after schema type changes.
- If bytes come from a custom format, slice/repack to 1 byte before handing them to the codec.
Example fix
// before ByteBuffer b = ByteBuffer.allocate(2).putShort((short)1); booleanCodec.deserializeNoBoxing(b, version); // throws: got 2 bytes // after ByteBuffer b = ByteBuffer.allocate(1).put((byte)1); booleanCodec.deserializeNoBoxing(b, version); // true
Defensive patterns
Strategy: type-guard
Validate before calling
if (bytes == null || bytes.remaining() != 1)
throw new IllegalArgumentException("boolean needs exactly 1 byte, got " + (bytes == null ? 0 : bytes.remaining())); Type guard
boolean isBooleanBuffer(ByteBuffer b) {
return b != null && b.remaining() == 1;
} Try / catch
try {
return booleanCodec.deserializeNoBoxing(bytes, protocolVersion);
} catch (InvalidTypeException e) {
log.warn("Non-boolean payload ({} bytes), treating as false", bytes.remaining());
return false;
} Prevention
- Encode booleans with put((byte)(b ? 1 : 0)), never putInt/putShort.
- Match codec to the actual column type; use tinyint codec for 1-byte signed ints.
- Slice per-value buffers so extra bytes from adjacent fields do not leak into remaining().
When it happens
Trigger: Calling booleanCodec.deserializeNoBoxing(bytes, protocolVersion) where bytes.remaining() != 1 — e.g. decoding an int, tinyint, or text column's bytes with the boolean codec.
Common situations: Column type changed between boolean and tinyint/int; storing "true"/"false" text in a column read as boolean; manual byte buffers that put more than one byte (e.g. putInt); custom protocol implementations writing padded values.
Related errors
- Invalid 64-bits long value, expecting 8 bytes but got
- Cannot parse boolean value from "%s"
- Invalid decimal value, expecting at least 4 bytes but got
- text or varchar values must be enclosed by single quotes
- %s is not a valid ASCII String
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/0382e69fa9c2a845.
Report an issue: GitHub.