apache/cassandra · error · ProtocolException
Out of bound timestamp, must be in
Error message
Out of bound timestamp, must be in [%d, %d] (got %d)
What it means
When a native-protocol v5+ client sends the TIMESTAMP flag in a QUERY/PREPARE message, the default write timestamp is read as a long. Long.MIN_VALUE is reserved internally as 'no timestamp', so a client sending exactly Long.MIN_VALUE is rejected with a ProtocolException during message decoding.
Solutions
- Change the client-provided timestamp to any value in [Long.MIN_VALUE+1, Long.MAX_VALUE].
- If 'no timestamp' is desired, omit the TIMESTAMP flag instead of sending Long.MIN_VALUE.
- Adjust driver configuration (e.g. default timestamp provider) to stop generating Long.MIN_VALUE.
Example fix
// before long ts = Long.MIN_VALUE; // rejected // after long ts = System.currentTimeMillis() * 1000L; // microseconds
Defensive patterns
Strategy: validation
Validate before calling
if (ts == Long.MIN_VALUE) throw new IllegalArgumentException("timestamp must be > Long.MIN_VALUE"); Try / catch
try { session.execute(stmt); } catch (ProtocolException e) { if (e.getMessage().startsWith("Out of bound timestamp")) { /* fix timestamp source */ } } Prevention
- Never use Long.MIN_VALUE as a timestamp sentinel
- Generate timestamps via currentTimeMillis()*1000 or driver defaults
- Omit the TIMESTAMP flag instead of sending a reserved value
When it happens
Trigger: A client explicitly sets the default timestamp to Long.MIN_VALUE (e.g. Session#setDeveloperDefaultTimestamp or driver config passing Long.MIN_VALUE) and issues a request over protocol v5+.
Common situations: Application code using Long.MIN_VALUE as a sentinel 'unset' timestamp; misconfigured driver default-timestamp option; handcrafted protocol clients.
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
- Invalid BATCH message type
- Invalid query kind in BATCH messages. Must be 0 or 1 but…
- Unexpected request expecting READY, AUTHENTICATE, ERROR or…
- Attempted to encode a response with an unset stream id:
- Cannot parse timestamp value from
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/e4bd32202e7158d6.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/QueryOptions.java:769
}
}
boolean skipMetadata = Flag.contains(flags, Flag.SKIP_METADATA);
flags = Flag.remove(flags, Flag.VALUES);
flags = Flag.remove(flags, Flag.SKIP_METADATA);
SpecificOptions options = SpecificOptions.DEFAULT;
if (!Flag.isEmpty(flags))
{
int pageSize = Flag.contains(flags, Flag.PAGE_SIZE) ? body.readInt() : -1;
PagingState pagingState = Flag.contains(flags, Flag.PAGING_STATE) ? PagingState.deserialize(CBUtil.readValueNoCopy(body), version) : null;
ConsistencyLevel serialConsistency = Flag.contains(flags, Flag.SERIAL_CONSISTENCY) ? CBUtil.readConsistencyLevel(body) : ConsistencyLevel.SERIAL;
long timestamp = Long.MIN_VALUE;
if (Flag.contains(flags, Flag.TIMESTAMP))
{
long ts = body.readLong();
if (ts == Long.MIN_VALUE)
throw new ProtocolException(String.format("Out of bound timestamp, must be in [%d, %d] (got %d)", Long.MIN_VALUE + 1, Long.MAX_VALUE, ts));
timestamp = ts;
}
String keyspace = Flag.contains(flags, Flag.KEYSPACE) ? CBUtil.readString(body) : null;
long nowInSeconds = Flag.contains(flags, Flag.NOW_IN_SECONDS) ? CassandraUInt.toLong(body.readInt())
: UNSET_NOWINSEC;
boolean eligibleForArtificialLatency = Flag.contains(flags, Flag.ELIGIBLE_FOR_ARTIFICIAL_LATENCY);
options = new SpecificOptions(pageSize, pagingState, serialConsistency, timestamp, keyspace, nowInSeconds, eligibleForArtificialLatency);
}
DefaultQueryOptions opts = new DefaultQueryOptions(consistency, null, values, skipMetadata, options, version);
return names == null ? opts : new OptionsWithNames(opts, names);
}
public void encode(QueryOptions options, ByteBuf dest, ProtocolVersion version)
{
CBUtil.writeConsistencyLevel(options.getConsistency(), dest);
int flags = gatherFlags(options, version);View on GitHub (pinned to 88fd0f6a0e)