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

  1. Restructure the operation so each serial read/write targets a single partition (one Paxos round per partition)
  2. Use light-weight transactions only on single-partition queries; for multi-partition atomicity move to Accord transactions or redesign the data model
  3. Remove SERIAL/LOCAL_SERIAL from multi-partition reads if serial semantics aren't needed — use plain quorum reads
  4. 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

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/5c8e9b3ec7321566. Report an issue: GitHub.