apache/cassandra · error · InvalidRequestException
Timestamp must be set either on BATCH or individual statemen
Error message
Timestamp must be set either on BATCH or individual statements:
What it means
When a batch-level USING TIMESTAMP is set, none of the individual statements may also set their own USING TIMESTAMP — the source of the write timestamp must be unambiguous. BatchStatement.validate() throws this InvalidRequestException naming the offending statement.
Source
Thrown at src/java/org/apache/cassandra/cql3/statements/BatchStatement.java:277
if (timestampSet)
{
if (hasConditions)
throw new InvalidRequestException("Cannot provide custom timestamp for conditional BATCH");
if (isCounter())
throw new InvalidRequestException("Cannot provide custom timestamp for counter BATCH");
}
boolean hasCounters = false;
boolean hasNonCounters = false;
boolean hasVirtualTables = false;
boolean hasRegularTables = false;
for (ModificationStatement statement : statements)
{
if (timestampSet && statement.isTimestampSet())
throw new InvalidRequestException("Timestamp must be set either on BATCH or individual statements: " + statement.source);
if (statement.isCounter())
hasCounters = true;
else
hasNonCounters = true;
if (statement.isVirtual())
hasVirtualTables = true;
else
hasRegularTables = true;
}
if (timestampSet && hasCounters)
throw new InvalidRequestException("Cannot provide custom timestamp for a BATCH containing counters");
if (isCounter() && hasNonCounters)
throw new InvalidRequestException("Cannot include non-counter statement in a counter batch");
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Remove USING TIMESTAMP from the individual statement named in the error, keeping the batch-level timestamp
- Or remove the batch-level USING TIMESTAMP and keep per-statement timestamps
Example fix
// before BEGIN BATCH USING TIMESTAMP 1000 INSERT INTO t (k,v) VALUES (1,'x') USING TIMESTAMP 2000; APPLY BATCH; // after BEGIN BATCH USING TIMESTAMP 1000 INSERT INTO t (k,v) VALUES (1,'x'); APPLY BATCH;
Defensive patterns
Strategy: validation
Validate before calling
if (batchUsesTimestamp && statements.stream().anyMatch(ModificationStatement::isTimestampSet))
throw new IllegalArgumentException("timestamp set both on BATCH and a child statement"); Try / catch
try { session.execute(batch); }
catch (InvalidQueryException e) {
if (e.getMessage().startsWith("Timestamp must be set either on BATCH")) { /* pick one level for the timestamp */ }
} Prevention
- Choose exactly one timestamp scope per batch: batch-level OR per-statement
- Have query builders assert mutual exclusivity of batch attrs and statement attrs
When it happens
Trigger: BEGIN BATCH USING TIMESTAMP n containing at least one statement whose isTimestampSet() is true (statement.timestamp reported in the message), via execute or prepare.
Common situations: Application code that appends USING TIMESTAMP to every INSERT while a batching layer also adds a batch-level timestamp; hand-written batches converted from single-statement templates.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Cannot provide custom timestamp for a BATCH containing count
- Invalid null value of timestamp
- Invalid timestamp value: <tval>
- Global TTL on the BATCH statement is not supported.
- Cannot provide custom timestamp for conditional BATCH
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/14e443ac4176079d.
Report an issue: GitHub.