{"record":{"id":"2a6868cf028f9764","repo":"apache/cassandra","slug":"cannot-provide-custom-timestamp-for-a-batch-contai","errorCode":null,"errorMessage":"Cannot provide custom timestamp for a BATCH containing counters","messagePattern":"Cannot provide custom timestamp for a BATCH containing counters","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/BatchStatement.java","lineNumber":291,"sourceCode":"\n        for (ModificationStatement statement : statements)\n        {\n            if (timestampSet && statement.isTimestampSet())\n                throw new InvalidRequestException(\"Timestamp must be set either on BATCH or individual statements: \" + statement.source);\n\n            if (statement.isCounter())\n                hasCounters = true;\n            else\n                hasNonCounters = true;\n\n            if (statement.isVirtual())\n                hasVirtualTables = true;\n            else\n                hasRegularTables = true;\n        }\n\n        if (timestampSet && hasCounters)\n            throw new InvalidRequestException(\"Cannot provide custom timestamp for a BATCH containing counters\");\n\n        if (isCounter() && hasNonCounters)\n            throw new InvalidRequestException(\"Cannot include non-counter statement in a counter batch\");\n\n        if (hasCounters && hasNonCounters)\n            throw new InvalidRequestException(\"Counter and non-counter mutations cannot exist in the same batch\");\n\n        if (isLogged() && hasCounters)\n            throw new InvalidRequestException(\"Cannot include a counter statement in a logged batch\");\n\n        if (isLogged() && hasVirtualTables)\n            throw new InvalidRequestException(\"Cannot include a virtual table statement in a logged batch\");\n\n        if (hasVirtualTables && hasRegularTables)\n            throw new InvalidRequestException(\"Mutations for virtual and regular tables cannot exist in the same batch\");\n\n        if (hasConditions && hasVirtualTables)\n            throw new InvalidRequestException(\"Conditional BATCH statements cannot include mutations for virtual tables\");","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java#L273-L309","documentation":"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.","triggerScenarios":"BEGIN BATCH ... USING TIMESTAMP n ... mixing (or solely containing) counter UPDATE statements with any other statements, executed or prepared.","commonSituations":"Generic batch helpers applying a global timestamp across mixed workloads; incrementing counters together with regular writes under one timestamped batch.","solutions":["Remove USING TIMESTAMP from the batch","Split the batch: counter statements in one batch, timestamped regular statements in another"],"exampleFix":"// before\nBEGIN BATCH USING TIMESTAMP 1000 UPDATE ctr SET c=c+1 WHERE k='a'; INSERT INTO t ...; APPLY BATCH;\n// after\nBEGIN BATCH UPDATE ctr SET c=c+1 WHERE k='a'; APPLY BATCH;\nBEGIN BATCH USING TIMESTAMP 1000 INSERT INTO t ...; APPLY BATCH;","handlingStrategy":"validation","validationCode":"boolean hasCounters = statements.stream().anyMatch(ModificationStatement::isCounter);\nif (batchUsesTimestamp && hasCounters) throw new IllegalArgumentException(\"remove USING TIMESTAMP or split counter statements out\");","typeGuard":null,"tryCatchPattern":"try { session.execute(batch); }\ncatch (InvalidQueryException e) {\n    if (e.getMessage().contains(\"BATCH containing counters\")) { /* split batch by table type */ }\n}","preventionTips":["Separate counter and non-counter workloads into distinct batches","Never let generic batch helpers apply global timestamps to mixed workloads"],"tags":["cql","batch","counters","timestamp"],"backgroundTag":"conflicting-config-options","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}