DynamoDB TransactionCanceledException: How to Fix It

TransactionCanceledException aborts the whole transaction. Read the CancellationReasons array to find which item failed and why — conditional check, conflict, or throttle.

3 min read· Updated Jul 26, 2026
On this page

TransactionCanceledException means DynamoDB aborted your entire transaction — with transactions being all-or-nothing, if one item couldn’t be applied, none were. The message alone is vague:

TransactionCanceledException: Transaction cancelled, please refer cancellation
reasons for specific reasons [ConditionalCheckFailed, None, None]

The real information is in the CancellationReasons array. Read it and the diagnosis is usually immediate.

Read the CancellationReasons array

CancellationReasons has one entry per item in your TransactWriteItems / TransactGetItems call, in the same order you supplied them. Each entry carries a Code (and sometimes a Message). Items that were fine show Code: "None"; the culprit shows something else.

try {
  await client.send(transactWriteCommand);
} catch (err) {
  if (err.name === "TransactionCanceledException") {
    err.CancellationReasons.forEach((r, i) => {
      if (r.Code !== "None") console.log(`item ${i} failed: ${r.Code} — ${r.Message}`);
    });
  }
}

So [ConditionalCheckFailed, None, None] means the first item’s condition failed; items two and three were fine. Map the index back to your input array to find the offending operation.

What each Code means

ConditionalCheckFailed

A ConditionExpression on that item wasn’t satisfied. This is often by design — an idempotency guard (attribute_not_exists(pk)) or an optimistic-lock version check. Decide whether it’s an expected branch or a real conflict, and handle accordingly. See ConditionalCheckFailedException for the patterns, which apply per-item inside a transaction too.

Tip: set ReturnValuesOnConditionCheckFailure: "ALL_OLD" on the item to get its current attributes back in the reason — so you can see why the condition failed without a separate read.

TransactionConflict

Another concurrent transaction or write touched one of the same items while yours was in flight, so DynamoDB cancelled yours to preserve isolation. Usually transient — retry with exponential backoff. Persistent conflicts mean contention on a hot item; reduce it by sharding the key or restructuring so fewer transactions collide.

ThrottlingError / ProvisionedThroughputExceeded

The table or an index didn’t have capacity for the transaction (which costs roughly 2× the write capacity of a normal write, for the two-phase protocol). Retry with backoff, and address capacity — auto scaling or on-demand. See ProvisionedThroughputExceededException.

ValidationError

One item’s request was malformed — a key that doesn’t match the schema, a bad expression, or two operations on the same item in one transaction (not allowed). Fix the offending operation.

None

That item was fine. It’s only listed to keep the array aligned with your input order.

Common gotchas that cause cancellations

  • Two actions on the same item in one transaction — DynamoDB rejects it. A transaction may not operate on the same item twice.
  • Up to 100 items / 4 MB per transaction — exceed it and the whole call is rejected.
  • Idempotency token reuse — reusing a ClientRequestToken with a different payload fails; reusing it with the same payload is the intended dedupe behavior.
  • Treating a ConditionalCheckFailed as a crash when it’s actually your expected “already exists / version moved” branch.

Diagnostic checklist

  1. Catch TransactionCanceledException and log CancellationReasons — don’t just log the message.
  2. Find the non-None entry; its index identifies the failed item.
  3. Match the Code: condition (design or conflict?), conflict (retry), throttle (capacity), validation (fix request).
  4. For conditions, use ReturnValuesOnConditionCheckFailure: ALL_OLD to see the item’s real state.
  5. Check for same-item-twice, size limits, or token reuse.

Inspect the real item state

Most transaction cancellations come down to an item not being in the state your condition assumed. Tablyne lets you open the exact item, see its current attributes and types, and understand why a condition failed — instead of blind-debugging a rolled-back transaction. Download Tablyne free.

Frequently asked questions

How do I find out why a DynamoDB transaction was cancelled?

Read the CancellationReasons array on the exception. It has one entry per item in your transaction, in the same order. Each entry has a Code — like ConditionalCheckFailed, TransactionConflict, or ThrottlingError — and None for items that were fine. The position tells you which item failed.

What is a TransactionConflict code?

It means another concurrent transaction or write touched one of the same items while yours was in flight, so DynamoDB cancelled yours to preserve isolation. This is usually transient — retry with backoff. Frequent conflicts point to contention on a hot item.

Does a cancelled transaction write anything?

No. DynamoDB transactions are all-or-nothing. If any item's condition or check fails, the entire transaction is rolled back and no item is modified.

Keep reading