apache/cassandra · error · MarshalException

Expected 8 or 0 byte value for a double (%d)

Error message

Expected 8 or 0 byte value for a double (%d)

What it means

MarshalException raised by DoubleSerializer.validate when a serialized double value on disk or on the wire is neither empty (null) nor exactly 8 bytes long. The input is corrupt or was produced by an incompatible writer, since a double always serializes to 8 bytes.

Source

Thrown at src/java/org/apache/cassandra/serializers/DoubleSerializer.java:45

{
    public static final DoubleSerializer instance = new DoubleSerializer();

    public <V> Double deserialize(V value, ValueAccessor<V> accessor)
    {
        if (accessor.isEmpty(value))
            return null;
        return accessor.toDouble(value);
    }

    public ByteBuffer serialize(Double value)
    {
        return (value == null) ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBufferUtil.bytes(value);
    }

    public <T> void validate(T value, ValueAccessor<T> accessor) throws MarshalException
    {
        if (accessor.size(value) != 8 && !accessor.isEmpty(value))
            throw new MarshalException(String.format("Expected 8 or 0 byte value for a double (%d)", accessor.size(value)));
    }

    public String toString(Double value)
    {
        return value == null ? "" : value.toString();
    }

    public Class<Double> getType()
    {
        return Double.class;
    }
}

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Serialize with DoubleSerializer.serialize(Double) so exactly 8 bytes are written
  2. Fix type mismatch: cast to double before writing, or correct the column type
  3. Convert 4-byte float data by reading as float and re-serializing as double
  4. If truncated on disk, restore/repair the data

Example fix

// before
ByteBuffer bad = ByteBuffer.allocate(4).putFloat(1.5f);
// after
ByteBuffer ok = DoubleSerializer.instance.serialize(Double.valueOf(1.5d));
Defensive patterns

Strategy: type-guard

Validate before calling

public static void checkDouble(ByteBuffer buf) {
    if (buf != null && buf.hasRemaining() && buf.remaining() != 8)
        throw new MarshalException("double must be 8 bytes, got " + buf.remaining());
}

Type guard

public static boolean isDoubleSized(ByteBuffer buf) {
    return buf == null || !buf.hasRemaining() || buf.remaining() == 8;
}

Try / catch

try {
    Double d = DoubleSerializer.instance.deserialize(buffer);
} catch (MarshalException e) {
    logger.warn("Bad double value: {}", e.getMessage());
}

Prevention

When it happens

Trigger: validate/deserialize on a buffer that is non-empty but not 8 bytes — e.g. a float (4 bytes) or int written into a double column, truncated cell data, or wrong type in a collection of doubles.

Common situations: Inserting Float into a double column via custom serialization; schema type mismatch after ALTER; partial writes/corruption; UDF returning wrong-width bytes.

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