apache/cassandra · error · InvalidTypeException

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

Error message

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

What it means

The bigint codec's deserializeNoBoxing() requires exactly 8 bytes on the wire, matching CQL's fixed 8-byte bigint encoding. A buffer with a different remaining size means the bytes are not a bigint value — usually the wrong codec was applied to the column's bytes.

Source

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

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

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

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

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

    /**
     * This codec maps a CQL {@link DataType#bigint()} to a Java {@link Long}.
     */
    private static class BigintCodec extends LongCodec
    {

        private static final BigintCodec instance = new BigintCodec();

        private BigintCodec()
        {
            super(DataType.bigint());
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Use the codec matching the column's declared type (int codec for 4-byte, bigint for 8-byte, varint for BigInteger).
  2. Fix the byte production side to emit exactly 8 bytes: ByteBuffer.allocate(8).putLong(value).
  3. Refresh prepared statements/codecs after any ALTER TABLE type change.
  4. If length is genuinely variable, the column is varint — switch to the bigInteger codec.

Example fix

// before
ByteBuffer b = ByteBuffer.allocate(4).putInt(42);
longCodec.deserializeNoBoxing(b, version); // throws: got 4 bytes
// after
ByteBuffer b = ByteBuffer.allocate(8).putLong(42L);
longCodec.deserializeNoBoxing(b, version); // 42
Defensive patterns

Strategy: type-guard

Validate before calling

if (bytes == null || bytes.remaining() != 8)
    throw new IllegalArgumentException("bigint needs exactly 8 bytes, got " + (bytes == null ? 0 : bytes.remaining()));

Type guard

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

Try / catch

try {
    return longCodec.deserializeNoBoxing(bytes, protocolVersion);
} catch (InvalidTypeException e) {
    // wrong codec or corrupt bytes; fall back to the declared column type
    return intCodec == null ? 0L : intCodec.deserializeNoBoxing(bytes, protocolVersion);
}

Prevention

When it happens

Trigger: Calling bigintCodec.deserializeNoBoxing(bytes, protocolVersion) (or deserialize/get on a Row with a bigint codec) where bytes.remaining() is 0 handled earlier but 1..7 or 9+ here — e.g. an int (4-byte) or varint column decoded as bigint.

Common situations: Schema changed from int to bigint (or vice versa) while cached codecs/prepared statements still assume the old width; manual byte assembly with ByteBuffer.putInt instead of putLong; reading a counter/varint column through the wrong codec.

Related errors


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