apache/cassandra · error · InvalidRequestException
The duration must have a millisecond precision. Was
Error message
The duration must have a millisecond precision. Was: %s
What it means
TimestampType stores instants with millisecond precision. When a duration value is validated for a timestamp column, the duration must have millisecond precision; durations with precision finer than milliseconds (micro/nanoseconds) are rejected with this invalid-request error.
Solutions
- Round or truncate the duration to whole milliseconds before binding (e.g. Duration.ofMillis(d.toMillis())).
- Adjust the literal to millisecond precision, e.g. PT0.123S instead of PT0.123456S.
- If sub-millisecond precision is required, store the value as a different type (e.g. duration or a custom encoding).
Example fix
// before Duration d = Duration.ofNanos(1_500_123L); stmt.set(0, d); // rejected // after stmt.set(0, Duration.ofMillis(d.toMillis()));
Defensive patterns
Strategy: validation
Validate before calling
// Java (driver): ensure millisecond precision before binding to a timestamp column
if (!duration.hasMillisecondPrecision())
duration = Duration.ofMillis(duration.toMillis()); // truncate to milliseconds Try / catch
try {
session.execute(stmt.bind(duration));
} catch (InvalidQueryException e) {
if (e.getMessage().contains("millisecond precision")) {
// truncate duration to millis and retry
}
} Prevention
- Truncate nanosecond-resolution durations with Duration.ofMillis(d.toMillis()) before binding.
- Avoid constructing durations from nanosecond sources when targeting timestamp columns.
- Keep duration literals at or coarser than millisecond granularity (e.g. PT0.123S).
When it happens
Trigger: Inserting or binding a Duration into a 'timestamp' column where duration.hasMillisecondPrecision() is false — i.e. the duration includes sub-millisecond components (nanos not a multiple of 1,000,000).
Common situations: Clients generating durations from java.time with nanosecond resolution (e.g. Duration.ofNanos) and binding them to timestamp columns; migrating high-resolution timing data from other systems into Cassandra timestamps.
Understand the failure class
Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.
Related errors
- The duration must have a day precision. Was
- Argument ' ' cannot be frozen; remove frozen<> modifier from
- Cannot provide custom timestamp for a BATCH containing…
- duration type is not supported for PRIMARY KEY column
- Durations are not allowed as map keys:
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/d85df4fd4b8892e9.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/db/marshal/TimestampType.java:173
{
return this == otherType || otherType == DateType.instance || otherType == LongType.instance;
}
public CQL3Type asCQL3Type()
{
return CQL3Type.Native.TIMESTAMP;
}
public TypeSerializer<Date> getSerializer()
{
return TimestampSerializer.instance;
}
@Override
protected void validateDuration(Duration duration)
{
if (!duration.hasMillisecondPrecision())
throw invalidRequest("The duration must have a millisecond precision. Was: %s", duration);
}
@Override
public ByteBuffer getMaskedValue()
{
return MASKED_VALUE;
}
}
View on GitHub (pinned to 88fd0f6a0e)