apache/cassandra · error · InvalidTypeException

Invalid 64-bits double value, expecting 8 bytes but got

Error message

Invalid 64-bits double value, expecting 8 bytes but got 

What it means

Thrown by the DoubleCodec's deserializeNoBoxing when the incoming ByteBuffer does not contain exactly 8 bytes, the wire size of a CQL double. A null or empty buffer deserializes to 0, but any other non-8-byte length is invalid and cannot be interpreted as a 64-bit IEEE-754 double.

Source

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

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

        @Override
        public ByteBuffer serializeNoBoxing(double value, ProtocolVersion protocolVersion)
        {
            ByteBuffer bb = ByteBuffer.allocate(8);
            bb.putDouble(0, value);
            return bb;
        }

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

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

    /**
     * This codec maps a CQL {@link DataType#cfloat()} to a Java {@link Float}.
     */
    private static class FloatCodec extends PrimitiveFloatCodec
    {

        private static final FloatCodec instance = new FloatCodec();

        private FloatCodec()
        {
            super(DataType.cfloat());
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Verify the column's CQL type matches double before deserializing (row.getColumnDefinitions().getType(i)).
  2. Check that the ByteBuffer passed in is exactly 8 bytes: log bytes.remaining() and the buffer's hex dump.
  3. If reading from a collection or UDT, use the provided collection codecs rather than manual slicing so element boundaries are honored.
  4. Re-read from the source with the correct type codec (e.g. FloatCodec for a 4-byte value).

Example fix

// before
float f = codecFor(Double.class).deserializeNoBoxing(buffer, ProtocolVersion.V4);
// after
DataType colType = row.getColumnDefinitions().getType("my_col");
if (colType == DataType.doublePrecision()) {
    double d = row.getDouble("my_col");
} else if (colType == DataType.cfloat()) {
    float f = row.getFloat("my_col");
}
Defensive patterns

Strategy: validation

Validate before calling

if (bytes == null || bytes.remaining() == 0) return 0d;
if (bytes.remaining() != 8)
    throw new IllegalArgumentException("Expected 8 bytes for double, got " + bytes.remaining());

Type guard

boolean isDoubleSized(ByteBuffer b) { return b != null && b.remaining() == 8; }

Try / catch

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

Prevention

When it happens

Trigger: Calling codec.deserializeNoBoxing(bytes, protocolVersion) (or deserialize) with a ByteBuffer whose remaining() is 1-7 or 9+ bytes, typically when reading a column that is not actually a double, or a truncated/corrupt value.

Common situations: Reading a column whose CQL type changed (e.g. float stored where double expected), manually slicing a composite/legacy payload at wrong offsets, or hand-rolled collection/UDT parsing that mis-sizes element buffers.

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/d97d443ffcce51c2. Report an issue: GitHub.