apache/cassandra · error · InvalidRequestException

No ORDER BY clause allowed within a transaction; %s statemen

Error message

No ORDER BY clause allowed within a transaction; %s statement %s

What it means

Cassandra rejects SELECT statements that carry an ORDER BY clause when executed inside an Accord transaction block. Ordering is not supported by the transactional read path, so any SELECT with orderings is rejected at prepare/validate time with an InvalidRequestException. The message includes the statement type and its source text.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/TransactionStatement.java:698

    }

    @Override
    public AuditLogContext getAuditLogContext()
    {
        return new AuditLogContext(AuditLogEntryType.TRANSACTION);
    }

    @Override
    public boolean eligibleAsPreparedStatement()
    {
        // false is the default, but still best to be explicit.
        return false;
    }

    private static void validate(SelectStatement.RawStatement select)
    {
        if (select.parameters.orderings != null && !select.parameters.orderings.isEmpty())
            throw invalidRequest(NO_ORDER_BY_IN_TXNS_MESSAGE, "SELECT", select.source);
        if (select.parameters.groups != null && !select.parameters.groups.isEmpty())
            throw invalidRequest(NO_GROUP_BY_IN_TXNS_MESSAGE, "SELECT", select.source);
    }

    private static void validate(SelectStatement prepared)
    {
        if (!prepared.table.isAccordEnabled())
            throw invalidRequest(TRANSACTIONS_DISABLED_ON_TABLE_MESSAGE, "SELECT", prepared.source);
        if (prepared.table.params.pendingDrop)
            throw invalidRequest(TRANSACTIONS_DISABLED_ON_TABLE_BEING_DROPPED_MESSAGE, "SELECT", prepared.source);
        if (prepared.table.isCounter())
            throw invalidRequest(NO_COUNTERS_IN_TXNS_MESSAGE, "SELECT", prepared.source);
        if (prepared.hasAggregation())
            throw invalidRequest(NO_AGGREGATION_IN_TXNS_MESSAGE, "SELECT", prepared.source);

        // when "LIMIT ?" this check can't be performed, so need to do again once the options are known
        if (prepared.getRestrictions().keyIsInRelation())
            checkTrue(prepared.isLimitMarker() || prepared.getLimit(null) == DataLimits.NO_LIMIT, NO_PARTITION_IN_CLAUSE_WITH_LIMIT, "SELECT", prepared.source);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Remove the ORDER BY clause from the SELECT inside the transaction
  2. Sort results client-side after the transaction returns
  3. Move the ordering query outside the transaction if atomicity is not required

Example fix

// before
BEGIN TRANSACTION
  SELECT ... FROM t WHERE pk = 1 ORDER BY ck DESC;
COMMIT TRANSACTION;
// after
BEGIN TRANSACTION
  SELECT ... FROM t WHERE pk = 1;
COMMIT TRANSACTION;
// then sort client-side
Defensive patterns

Strategy: validation

Validate before calling

if (query.toUpperCase().matches("(?s).*ORDER\\s+BY.*") && inTransaction) throw new IllegalArgumentException("ORDER BY not allowed in transaction");

Try / catch

try { session.execute(txnCql); } catch (InvalidRequestException e) { if (e.getMessage().contains("No ORDER BY clause allowed within a transaction")) { /* strip ORDER BY and retry */ } else throw e; }

Prevention

When it happens

Trigger: Running a transaction (BEGIN TRANSACTION ... COMIT) whose SELECT over an Accord-enabled table includes `ORDER BY <column>` in its ordering clause; caught in TransactionStatement.validate(SelectStatement.RawStatement) when select.parameters.orderings is non-empty.

Common situations: Porting existing interactive CQL SELECTs into a transaction unchanged; copying application queries that relied on per-partition ORDER BY into a txn block.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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