apache/cassandra · error · MarshalException

Expected 8 byte long for time (%d)

Error message

Expected 8 byte long for time (%d)

What it means

TimeSerializer.validate enforces that a 'time' value occupies exactly 8 bytes (a long of nanoseconds since midnight). This error indicates the binary value has a different length, so it cannot be a valid time encoding.

Source

Thrown at src/java/org/apache/cassandra/serializers/TimeSerializer.java:74

                throw new MarshalException(String.format("Unable to make long (for time) from: '%s'", source), e);
            }
        }

        // Last chance, attempt to parse as time string
        try
        {
            return parseTimeStrictly(source);
        }
        catch (IllegalArgumentException e1)
        {
            throw new MarshalException(String.format("(TimeType) Unable to coerce '%s' to a formatted time (long)", source), e1);
        }
    }

    public <V> void validate(V value, ValueAccessor<V> accessor) throws MarshalException
    {
        if (accessor.size(value) != 8)
            throw new MarshalException(String.format("Expected 8 byte long for time (%d)", accessor.size(value)));
    }

    @Override
    public boolean shouldQuoteCQLLiterals()
    {
        return true;
    }

    public String toString(Long value)
    {
        if (value == null)
            return "null";

        int nano = (int)(value % 1000);
        value -= nano;
        value /= 1000;
        int micro = (int)(value % 1000);
        value -= micro;

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Ensure the value is exactly 8 bytes: ByteBuffer.allocate(8).putLong(nanosSinceMidnight)
  2. Use the driver's time codec / LocalTime mapping instead of raw bytes
  3. Verify the target column type via metadata before binding
  4. Re-check any ETL code that packs values by hand

Example fix

// before
ByteBuffer v = Bytes.fromHexString("0x0000"); // 2 bytes
// after
ByteBuffer v = ByteBuffer.allocate(8).putLong(TimeUnit.HOURS.toNanos(13));
Defensive patterns

Strategy: type-guard

Validate before calling

if (buf == null || buf.remaining() != 8) throw new IllegalArgumentException("time value must be exactly 8 bytes, got " + (buf == null ? 0 : buf.remaining()));

Type guard

boolean isWellFormedTimeBytes(ByteBuffer v) { return v != null && v.remaining() == 8; }

Try / catch

try {
  serializer.validate(value, byteBufferAccessor);
} catch (MarshalException e) {
  throw new DataCorruptionException("non-8-byte value in time column", e);
}

Prevention

When it happens

Trigger: Binding a 4-byte int, a variable-length string's bytes, or an empty buffer as a time value; deserializing a column whose bytes came from a different type; custom protocol code writing the wrong width.

Common situations: Type confusion between int/date columns and time columns after schema changes; hand-built ByteBuffers in test harnesses; drivers misconfiguring codecs.

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