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

  1. Ensure the value is written as a 32-bit float: use FloatType serializers or ByteBufferUtil.bytes(float), not bytes(double).
  2. Check the client-side field type; convert double to float before writing if the column is float.
  3. Fix the column type in the schema (double vs float) to match what the application actually writes.
  4. 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

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


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)