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

  1. Change the client-provided timestamp to any value in [Long.MIN_VALUE+1, Long.MAX_VALUE].
  2. If 'no timestamp' is desired, omit the TIMESTAMP flag instead of sending Long.MIN_VALUE.
  3. 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

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


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)