apache/cassandra · error · InvalidRequestException
Cannot provide custom timestamp for counter BATCH
Error message
Cannot provide custom timestamp for counter BATCH
What it means
Counter mutations have no user-settable writetime (they use server-side counters), so a counter batch may not include USING TIMESTAMP. BatchStatement.validate() throws this InvalidRequestException when timestampSet && isCounter().
Source
Thrown at src/java/org/apache/cassandra/cql3/statements/BatchStatement.java:265
ModificationStatement.TableAuthorizationState authorizationState = new ModificationStatement.TableAuthorizationState();
for (ModificationStatement statement : statements)
statement.authorize(state, authorizationState);
}
// Validates a prepared batch statement without validating its nested statements.
public void validate() throws InvalidRequestException
{
if (attrs.isTimeToLiveSet())
throw new InvalidRequestException("Global TTL on the BATCH statement is not supported.");
boolean timestampSet = attrs.isTimestampSet();
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;
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Remove USING TIMESTAMP from the counter batch
- If timestamp control is required, use regular (non-counter) tables instead of counters
Example fix
// before BEGIN BATCH USING TIMESTAMP 1234 UPDATE counters SET c = c + 1 WHERE k = 'a'; APPLY BATCH; // after BEGIN BATCH UPDATE counters SET c = c + 1 WHERE k = 'a'; APPLY BATCH;
Defensive patterns
Strategy: validation
Validate before calling
boolean isCounterBatch = statements.stream().allMatch(BatchStatement::isCounter);
if (isCounterBatch && batchUsesTimestamp) throw new IllegalArgumentException("USING TIMESTAMP not allowed on counter batches"); Try / catch
try { session.execute(batch); }
catch (InvalidQueryException e) {
if (e.getMessage().contains("custom timestamp for counter BATCH")) { /* strip USING TIMESTAMP */ }
} Prevention
- Counters do not support client timestamps — never generate USING TIMESTAMP on counter writes
- Filter by table type before applying global batch options
When it happens
Trigger: BEGIN BATCH ... USING TIMESTAMP n ... where all statements target counter tables (isCounter() true), executed directly or via prepare.
Common situations: Reusing a generic write helper that always sets timestamps on batches; migrating regular-column writes to counters without stripping USING TIMESTAMP.
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
- Cannot include non-counter statement in a counter batch
- Global TTL on the BATCH statement is not supported.
- Cannot provide custom timestamp for conditional BATCH
- Timestamp must be set either on BATCH or individual statemen
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/4d6b4f8e163baef7.
Report an issue: GitHub.