apache/cassandra · error · InvalidRequestException
SERIAL/LOCAL_SERIAL consistency may only be requested for on
Error message
SERIAL/LOCAL_SERIAL consistency may only be requested for one partition at a time
What it means
Paxos serial (LWT) operations operate on exactly one partition per protocol round. When a serial read is issued as a group containing more than one partition query, Cassandra rejects it with this InvalidRequestException because a single Paxos round cannot cover multiple partitions.
Source
Thrown at src/java/org/apache/cassandra/service/paxos/Paxos.java:895
casWriteMetrics.addNano(latency);
writeMetricsMap.get(consistencyForConsensus).addNano(latency);
}
}
private static RowIterator conditionNotMet(FilteredPartition read)
{
Tracing.trace("CAS precondition rejected", read);
casWriteMetrics.conditionNotMet.inc();
return read.rowIterator(false);
}
public static ConsensusAttemptResult read(SinglePartitionReadCommand.Group group, ConsistencyLevel consistencyForConsensus, Dispatcher.RequestTime requestTime, long minHLC)
throws InvalidRequestException, UnavailableException, ReadFailureException, ReadTimeoutException
{
long start = nanoTime();
if (group.queries.size() > 1)
throw new InvalidRequestException("SERIAL/LOCAL_SERIAL consistency may only be requested for one partition at a time");
long deadline = requestTime.computeDeadline(DatabaseDescriptor.getReadRpcTimeout(NANOSECONDS));
int failedAttemptsDueToContention = 0;
Ballot minimumBallot = Ballot.atUnixMicrosWithLsb(minHLC, 0, GLOBAL);
SinglePartitionReadCommand read = group.queries.get(0);
// Allow potential txn conflicts since Paxos will manage them
read = read.withTransactionalSettings(false, read.nowInSec());
try (PaxosOperationLock lock = PaxosState.lock(read.partitionKey(), read.metadata(), deadline, consistencyForConsensus, false))
{
while (true)
{
// does the work of applying in-progress writes; throws UAE or timeout if it can't
final BeginResult begin = begin(deadline, read, consistencyForConsensus, false, minimumBallot, failedAttemptsDueToContention, requestTime);
failedAttemptsDueToContention = begin.failedAttemptsDueToContention;
if (begin.retryWithNewConsenusProtocol)
{
casReadMetrics.beginMigrationRejects.mark();View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Restructure the operation so each serial read/write targets a single partition (one Paxos round per partition)
- Use light-weight transactions only on single-partition queries; for multi-partition atomicity move to Accord transactions or redesign the data model
- Remove SERIAL/LOCAL_SERIAL from multi-partition reads if serial semantics aren't needed — use plain quorum reads
- Split the batch into per-partition statements executed separately
Example fix
// before: multi-partition serial read select = select().serialConsistency(SERIAL); // group of 2 partitions // after: per-partition serial reads for (cmd : queries) execute(cmd.bind(partition).serialConsistency(SERIAL));
Defensive patterns
Strategy: validation
Validate before calling
// only set serial consistency for single-partition statements if (statementQueriesSinglePartition(stmt)) stmt.setSerialConsistency(ConsistencyLevel.SERIAL);
Try / catch
try { session.execute(stmt); }
catch (InvalidRequestException e) { /* split into per-partition statements without serial consistency on groups */ } Prevention
- Use LWT/SERIAL only on single-partition queries
- Do not mix conditional writes on multiple partitions in one batch
- Redesign multi-partition atomicity needs around Accord transactions or denormalization
When it happens
Trigger: Executing a batched/multi-partition SELECT with consistency SERIAL or LOCAL_SERIAL (e.g. a batch containing LWT conditions on multiple partitions, or a partition-range/multi-partition read command group issued with serial consistency).
Common situations: Application batches mixing conditional writes across partitions; drivers issuing multi-partition reads with serial consistency after a refactor; ORMs generating multi-row serial queries; misuse of serial consistency on non-single-partition SELECTs.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot provide custom timestamp for conditional BATCH
- Counter and non-counter mutations cannot exist in the same b
- Conditional BATCH statements cannot include mutations for vi
- Batch with conditions cannot span multiple tables: %s
- Invalid empty consistency level
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/5c8e9b3ec7321566.
Report an issue: GitHub.