apache/cassandra · error · InvalidTypeException

Invalid 32-bits float value, expecting 4 bytes but got

Error message

Invalid 32-bits float value, expecting 4 bytes but got 

What it means

Thrown by FloatCodec.deserializeNoBoxing when the ByteBuffer does not contain exactly 4 bytes, the wire size of a CQL float. Empty or null buffers yield 0, but any other length is rejected since a 32-bit IEEE-754 float cannot be read from a different-size buffer.

Source

Thrown at src/java/org/apache/cassandra/cql3/functions/types/TypeCodec.java:1472

        {
            if (value == null) return "NULL";
            return Float.toString(value);
        }

        @Override
        public ByteBuffer serializeNoBoxing(float value, ProtocolVersion protocolVersion)
        {
            ByteBuffer bb = ByteBuffer.allocate(4);
            bb.putFloat(0, value);
            return bb;
        }

        @Override
        public float deserializeNoBoxing(ByteBuffer bytes, ProtocolVersion protocolVersion)
        {
            if (bytes == null || bytes.remaining() == 0) return 0;
            if (bytes.remaining() != 4)
                throw new InvalidTypeException(
                "Invalid 32-bits float value, expecting 4 bytes but got " + bytes.remaining());

            return bytes.getFloat(bytes.position());
        }
    }

    /**
     * This codec maps a CQL {@link DataType#inet()} to a Java {@link InetAddress}.
     */
    private static class InetCodec extends TypeCodec<InetAddress>
    {

        private static final InetCodec instance = new InetCodec();

        private InetCodec()
        {
            super(DataType.inet(), InetAddress.class);
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Confirm the target column's CQL type is 'float' (4 bytes) and not 'double' (8 bytes).
  2. Log bytes.remaining() when the error occurs to identify what type is actually encoded.
  3. Use the DoubleCodec when the underlying type is double, or re-migrate the column to the intended type.
  4. Use row.getFloat/getDouble via the typed API so codec selection is automatic.

Example fix

// before
float f = new FloatCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4); // bytes is 8
// after
if (bytes.remaining() == 8) {
    double d = new DoubleCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
} else {
    float f = new FloatCodec().deserializeNoBoxing(bytes, ProtocolVersion.V4);
}
Defensive patterns

Strategy: validation

Validate before calling

if (bytes == null || bytes.remaining() == 0) return 0f;
if (bytes.remaining() != 4)
    throw new IllegalArgumentException("Expected 4 bytes for float, got " + bytes.remaining());

Type guard

boolean isFloatSized(ByteBuffer b) { return b != null && b.remaining() == 4; }

Try / catch

try { return codec.deserializeNoBoxing(bytes, protocolVersion); }
catch (InvalidTypeException e) {
    log.warn("Float deserialization failed: {} (remaining={})", e.getMessage(), bytes.remaining());
    return Float.NaN;
}

Prevention

When it happens

Trigger: Calling FloatCodec.deserializeNoBoxing(bytes, protocolVersion) with a ByteBuffer whose remaining() is not 4, e.g. deserializing a double (8 bytes), a smallint, or a truncated payload as a float.

Common situations: CQL type drift between environments (column changed from float to double), wrong codec selected in manual UDT/collection parsing, or corrupt values in SSTable/legacy data imports.

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/3bc967de2178c619. Report an issue: GitHub.