apache/cassandra · error · InvalidRequestException

Out of bound timestamp, must be in

Error message

Out of bound timestamp, must be in [%d, %d]

What it means

RowUpdateBuilder stores the write timestamp in the DeletionTime; Long.MIN_VALUE is reserved internally to mean 'no timestamp' (in Selection, sstable stats, etc.), so a caller passing exactly Long.MIN_VALUE as the timestamp is rejected with InvalidRequestException to avoid that sentinel colliding with a real timestamp.

Solutions

  1. Use a valid timestamp in [Long.MIN_VALUE+1, Long.MAX_VALUE]; pick micros-since-epoch values
  2. Replace Long.MIN_VALUE 'unset' sentinels with a separate boolean/Optional before building the update
  3. Guard timestamp computation against underflow
  4. If you truly don't care, let the builder use the default now-based timestamp instead of passing one

Example fix

// before
long ts = Long.MIN_VALUE; // 'unset'
new RowUpdateBuilder(cfm, now, ts).newRow(key).add(...);
// after
long ts = unset ? FBUtilities.timestampMicros() : providedTs; // never MIN_VALUE
new RowUpdateBuilder(cfm, now, ts).newRow(key).add(...);
Defensive patterns

Strategy: validation

Validate before calling

if (timestamp == Long.MIN_VALUE) timestamp = System.currentTimeMillis() * 1000; // or reject

Try / catch

try { new RowUpdateBuilder(cfm, now, ts)...; } catch (InvalidRequestException e) { if (e.getMessage().startsWith("Out of bound timestamp")) useDefaultTimestamp(); else throw e; }

Prevention

When it happens

Trigger: Calling new RowUpdateBuilder(...) (or mutations built from it, e.g. in internal code/tests) with timestamp == Long.MIN_VALUE, typically from uninitialized `long timestamp = Long.MIN_VALUE` defaults or clients using Long.MIN_VALUE as 'unset'.

Common situations: Internal tooling/tests that default a timestamp field to Long.MIN_VALUE; deserializing client timestamps where an 'unset' marker was mapped to Long.MIN_VALUE; arithmetic underflow when computing timestamps (e.g. base - offset).

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/640eefb34ac26466. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/RowUpdateBuilder.java:104

                            QueryOptions options,
                            long timestamp,
                            long nowInSec,
                            int ttl,
                            Map<DecoratedKey, Partition> prefetchedRows) throws InvalidRequestException
    {
        this.metadata = metadata;
        this.options = options;
        this.clientState = clientState;
        this.nowInSec = nowInSec;
        this.timestamp = timestamp;
        this.ttl = ttl;

        this.deletionTime = DeletionTime.build(timestamp, nowInSec);
        this.prefetchedRows = prefetchedRows;
        // We use MIN_VALUE internally to mean the absence of of timestamp (in Selection, in sstable stats, ...), so exclude
        // it to avoid potential confusion.
        if (timestamp == Long.MIN_VALUE)
            throw new InvalidRequestException(String.format("Out of bound timestamp, must be in [%d, %d]", Long.MIN_VALUE + 1, Long.MAX_VALUE));

        areValueSizeGuardrailsEnabled = Guardrails.columnValueSize.enabled(clientState)
                                        || Guardrails.columnBlobValueSize.enabled(clientState)
                                        || Guardrails.columnAsciiValueSize.enabled(clientState)
                                        || Guardrails.columnTextAndVarcharValueSize.enabled(clientState);
    }

    @Override
    public QueryOptions options()
    {
        return options;
    }

    public <V> void newRow(Clustering<V> clustering) throws InvalidRequestException
    {
        if (metadata.isCompactTable())
        {
            if (TableMetadata.Flag.isDense(metadata.flags) && !TableMetadata.Flag.isCompound(metadata.flags))

View on GitHub (pinned to 88fd0f6a0e)