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
- Ensure the value is exactly 8 bytes: ByteBuffer.allocate(8).putLong(nanosSinceMidnight)
- Use the driver's time codec / LocalTime mapping instead of raw bytes
- Verify the target column type via metadata before binding
- 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
- Build time payloads with ByteBuffer.allocate(8).putLong(...)
- Use driver codecs rather than manual byte packing
- Verify column types via metadata before raw binding
- Check ETL buffer slicing logic for off-by-width bugs
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
- Expected 4 byte long for date (%d)
- Unable to make long (for time) from: '%s'
- (TimeType) Unable to coerce '%s' to a formatted time (long)
- Expected 8 or 0 byte long for date (%d)
- Not enough bytes to read size of %dth field %s
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/904ecd19cdcefece.
Report an issue: GitHub.