apache/cassandra · error · MarshalException
Expected 4 or 0 byte value for a float
Error message
Expected 4 or 0 byte value for a float (%d)
What it means
FloatSerializer.validate() enforces that a serialized float occupies exactly 4 bytes (or 0 bytes for the empty-value case). Any other length means the bytes are not a valid 32-bit IEEE-754 float, so a MarshalException is thrown. This protects against deserializing garbage as a float.
Solutions
- Ensure the value is written as a 32-bit float: use FloatType serializers or ByteBufferUtil.bytes(float), not bytes(double).
- Check the client-side field type; convert double to float before writing if the column is float.
- Fix the column type in the schema (double vs float) to match what the application actually writes.
- Validate the byte length before writing: buffer.remaining() must be 4 (or 0 for empty).
Example fix
// before ByteBuffer bytes = ByteBuffer.allocate(8).putDouble(3.14d); // after ByteBuffer bytes = ByteBuffer.allocate(4).putFloat((float) 3.14d);
Defensive patterns
Strategy: validation
Validate before calling
if (buf != null && buf.remaining() != 4 && buf.remaining() != 0) throw new IllegalArgumentException("float needs exactly 4 bytes, got " + buf.remaining()); Type guard
boolean isValidFloatBytes(java.nio.ByteBuffer b) { return b == null || b.remaining() == 0 || b.remaining() == 4; } Try / catch
try { floatSerializer.validate(buf, accessor); } catch (org.apache.cassandra.exceptions.MarshalException e) { log.error("invalid float bytes: {}", e.getMessage()); throw new IllegalArgumentException(e); } Prevention
- Always serialize floats via the type's serializer or putFloat, never putDouble
- Add a remaining()==4 assertion in any custom serialization pipeline
- Keep column type (float vs double) in sync with the application field type
When it happens
Trigger: Calling FloatSerializer.validate(value, accessor) (directly or via a FloatType column validation) with a buffer whose size is not 4 and not empty, e.g. an 8-byte double or a 1-byte blob written into a float column.
Common situations: Application writes a Java double (8 bytes) or ByteBuffer of wrong length into a float column; a migration or ETL tool serializes with the wrong type; driver protocol mismatch writing blob bytes into float-typed columns; hand-rolled serialization writing an extra byte.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- EmptyType only accept empty values
- Expected 4 or 0 byte int
- Expected 4 or 16 byte inetaddress; got
- Expected 0 or at least 4 bytes
- Expected 2 bytes for a smallint
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/451c7dfae75bdb13.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/serializers/FloatSerializer.java:46
public static final FloatSerializer instance = new FloatSerializer();
public <V> Float deserialize(V value, ValueAccessor<V> accessor)
{
if (accessor.isEmpty(value))
return null;
return accessor.toFloat(value);
}
public ByteBuffer serialize(Float value)
{
return (value == null) ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBufferUtil.bytes(value);
}
public <V> void validate(V value, ValueAccessor<V> accessor) throws MarshalException
{
if (accessor.size(value) != 4 && !accessor.isEmpty(value))
throw new MarshalException(String.format("Expected 4 or 0 byte value for a float (%d)", accessor.size(value)));
}
public String toString(Float value)
{
return value == null ? "" : String.valueOf(value);
}
public Class<Float> getType()
{
return Float.class;
}
}
View on GitHub (pinned to 88fd0f6a0e)