apache/cassandra · error · InvalidRequestException
Cannot provide custom timestamp for a BATCH containing count
Error message
Cannot provide custom timestamp for a BATCH containing counters
What it means
A batch-level USING TIMESTAMP cannot be combined with any counter statements in the batch, since counter writes cannot carry a custom timestamp. Thrown by BatchStatement.validate() when timestampSet && hasCounters.
Source
Thrown at src/java/org/apache/cassandra/cql3/statements/BatchStatement.java:291
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");
if (hasCounters && hasNonCounters)
throw new InvalidRequestException("Counter and non-counter mutations cannot exist in the same batch");
if (isLogged() && hasCounters)
throw new InvalidRequestException("Cannot include a counter statement in a logged batch");
if (isLogged() && hasVirtualTables)
throw new InvalidRequestException("Cannot include a virtual table statement in a logged batch");
if (hasVirtualTables && hasRegularTables)
throw new InvalidRequestException("Mutations for virtual and regular tables cannot exist in the same batch");
if (hasConditions && hasVirtualTables)
throw new InvalidRequestException("Conditional BATCH statements cannot include mutations for virtual tables");View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Remove USING TIMESTAMP from the batch
- Split the batch: counter statements in one batch, timestamped regular statements in another
Example fix
// before BEGIN BATCH USING TIMESTAMP 1000 UPDATE ctr SET c=c+1 WHERE k='a'; INSERT INTO t ...; APPLY BATCH; // after BEGIN BATCH UPDATE ctr SET c=c+1 WHERE k='a'; APPLY BATCH; BEGIN BATCH USING TIMESTAMP 1000 INSERT INTO t ...; APPLY BATCH;
Defensive patterns
Strategy: validation
Validate before calling
boolean hasCounters = statements.stream().anyMatch(ModificationStatement::isCounter);
if (batchUsesTimestamp && hasCounters) throw new IllegalArgumentException("remove USING TIMESTAMP or split counter statements out"); Try / catch
try { session.execute(batch); }
catch (InvalidQueryException e) {
if (e.getMessage().contains("BATCH containing counters")) { /* split batch by table type */ }
} Prevention
- Separate counter and non-counter workloads into distinct batches
- Never let generic batch helpers apply global timestamps to mixed workloads
When it happens
Trigger: BEGIN BATCH ... USING TIMESTAMP n ... mixing (or solely containing) counter UPDATE statements with any other statements, executed or prepared.
Common situations: Generic batch helpers applying a global timestamp across mixed workloads; incrementing counters together with regular writes under one timestamped batch.
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 counter BATCH
- Timestamp must be set either on BATCH or individual statemen
- Cannot include non-counter statement in a counter batch
- Invalid null value of timestamp
- Invalid timestamp value: <tval>
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/2a6868cf028f9764.
Report an issue: GitHub.