apache/cassandra · error · MarshalException
Unable to make long (for time) from: '%s'
Error message
Unable to make long (for time) from: '%s'
What it means
TimeSerializer.timeStringToLong first attempts to parse the input as a plain long nanosecond-of-day value. If it is numeric but outside [0, 86399999999] (one day of nanos), or otherwise not a valid long, it throws NumberFormatException which is wrapped into this MarshalException. CQL 'time' values are nanoseconds since midnight stored as an 8-byte long.
Source
Thrown at src/java/org/apache/cassandra/serializers/TimeSerializer.java:56
{
return value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBufferUtil.bytes(value);
}
public static Long timeStringToLong(String source) throws MarshalException
{
// nano since start of day, raw
if (timePattern.matcher(source).matches())
{
try
{
long result = Long.parseLong(source);
if (result < 0 || result >= TimeUnit.DAYS.toNanos(1))
throw new NumberFormatException("Input long out of bounds: " + source);
return result;
}
catch (NumberFormatException e)
{
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)));View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Supply nanoseconds since midnight within [0, 86399999999], e.g. '64989000000000' for 05:03:09
- Or use the hh:mm:ss[.fff] time string form, which is parsed by parseTimeStrictly instead
- Convert millis to nanos explicitly: TimeUnit.MILLISECONDS.toNanos(millisOfDay)
- Pre-check: long n = Long.parseLong(s); assert n >= 0 && n < TimeUnit.DAYS.toNanos(1);
Example fix
// before
session.execute("INSERT INTO t (tm) VALUES (?)", "86400000000000"); // 1 day, out of bounds
// after
session.execute("INSERT INTO t (tm) VALUES (?)", "86399999999999"); // 23:59:59.999999999 Defensive patterns
Strategy: validation
Validate before calling
long n;
try { n = Long.parseLong(input); } catch (NumberFormatException e) { throw new IllegalArgumentException("not a time long"); }
if (n < 0 || n >= TimeUnit.DAYS.toNanos(1)) throw new IllegalArgumentException("time nanos out of [0, 86399999999]: " + input); Type guard
boolean isValidTimeNanos(String s) {
try { long n = Long.parseLong(s); return n >= 0 && n < TimeUnit.DAYS.toNanos(1); }
catch (NumberFormatException e) { return false; }
} Try / catch
try {
long nanos = TimeSerializer.timeStringToLong(input);
} catch (MarshalException e) {
throw new BadRequestException("time must be nanos since midnight (0..86399999999) or HH:MM:SS[.fff]");
} Prevention
- Be explicit about units: CQL time is nanoseconds, not millis
- Clamp derived values to less than one day before insert
- Prefer sending LocalTime objects via driver codecs
- Add range assertions in the persistence layer
When it happens
Trigger: Inserting a quoted numeric string like '86400000000000' (exactly one day, out of bounds) or '-1' into a time column; passing '12345678901234567890' which overflows long.
Common situations: Confusing milliseconds with nanoseconds (a millis-since-midnight value can be in range but wrong; an epoch-millis value like 1725872400000 exceeds the day bound); off-by-one at the day boundary; unit confusion from other languages' time types.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- The duration months must be a 32 bits integer but was: %d
- The duration days must be a 32 bits integer but was: %d
- Input date %s is greater than max supported date %s
- (TimeType) Unable to coerce '%s' to a formatted time (long)
- Expected 8 byte long for time (%d)
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/2bc5a3cee533bfe3.
Report an issue: GitHub.