apache/cassandra · error · InvalidRequestException

Transaction contains multiple updates to the same key and fi

Error message

Transaction contains multiple updates to the same key and fields

What it means

TransactionStatement.mergeColumnsIfNoDuplicates merges the Columns touched by two transaction operations and throws InvalidRequestException (with DUPLICATE_KEYS_IN_SAME_TRANSACTION_MESSAGE) when the merged set is smaller than the sum of sizes, proving the same key/field was updated more than once in the transaction. Transactions must not contain conflicting duplicate writes.

Source

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

            idx++;
        }
        return fragments;
    }

    private static void validateOnlyModifyPrimaryKeyColumnPairOnce(HashMap<Object, Columns> seenColumns,
                                                                   ModificationStatement statement, List<TxnWrite.Fragment> writeFragments)
    {
        Columns regularColumns = statement.updatedColumns().columns(false);
        statement.forEachRowKey(writeFragments, seenColumns, regularColumns, TransactionStatement::mergeColumnsIfNoDuplicates);
        Columns staticColumns = statement.updatedColumns().columns(true);
        statement.forEachPartitionKey(writeFragments, seenColumns, staticColumns, TransactionStatement::mergeColumnsIfNoDuplicates);
    }

    private static Columns mergeColumnsIfNoDuplicates(Columns existing, Columns add)
    {
        Columns merged = existing.mergeTo(add);
        if (merged.size() != existing.size() + add.size())
            throw invalidRequest(DUPLICATE_KEYS_IN_SAME_TRANSACTION_MESSAGE);
        return merged;
    }

    private ConsistencyLevel consistencyLevelForAccordRead(ClusterMetadata cm, TableMetadatas.Complete tables, Keys keys, @Nullable ConsistencyLevel consistencyLevel)
    {
        // Write transactions are read/write so it creates a read and ends up needing a consistency level
        // which is fine to leave null
        if (keys.isEmpty())
            return null;

        // Null means no specific consistency behavior is required from Accord, it's functionally similar to
        // reading at ONE if you are reading data that wasn't written via Accord
        if (consistencyLevel == null)
            return null;

        for (Key key : keys)
        {
            // readCLForMode should return either null or the supplied consistency level

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Remove the duplicated update to the same key and fields from the transaction
  2. Merge the two updates into a single UPDATE setting all needed fields once
  3. If updates must combine values, do it in one statement (e.g. set both columns in one UPDATE) rather than two sequential statements

Example fix

// before
BEGIN TRANSACTION
  UPDATE t SET v = 1 WHERE pk = 1;
  UPDATE t SET v = 2 WHERE pk = 1; -- duplicate key+field
COMMIT TRANSACTION
// after
BEGIN TRANSACTION
  UPDATE t SET v = 2 WHERE pk = 1;
COMMIT TRANSACTION
Defensive patterns

Strategy: validation

Validate before calling

// track (key, field) pairs in the transaction before submitting
Set<String> seen = new HashSet<>();
for (Update u : updates) { String k = u.key() + ":" + u.field(); if (!seen.add(k)) throw new IllegalArgumentException("duplicate update " + k); }

Try / catch

try { session.execute(txnStatement); }
catch (InvalidRequestException e) { if (e.getMessage().contains("multiple updates")) { /* deduplicate transaction body */ } }

Prevention

When it happens

Trigger: A transaction (LET/UPDATE/OBJECT-style statement) performs two updates affecting the same primary-key row and the same columns, e.g. two UPDATEs to the same partition/row keys and overlapping fields.

Common situations: Repeating the same row update twice in one transaction block; variable bindings causing two LET-bound updates to collapse onto the same key; copy-paste duplication in transaction bodies.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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