TransactionInProgressException
TL;DR — A TransactWriteItems retry carried the same ClientRequestToken as an attempt that is still executing. This is usually your client timing out faster than the transaction completes, so the SDK's retry collides with the in-flight original. Keep retrying with backoff — a later retry after the original finishes returns the idempotent success — and tune timeouts so at least one retry lands after ~5 seconds.
What it means
TransactionInProgressException: The transaction with the given request token
is already in progress.ClientRequestToken makes TransactWriteItems idempotent: identical calls within a 10-minute window count as one transaction. While the first attempt is still being processed, a second call with the same token can't be answered yet — it's neither a duplicate of a completed transaction nor a new one — so DynamoDB rejects it with this exception. It's a timing signal, not a data error.
Why it happens
- Client timeout shorter than transaction latency — the request timeout fires, the SDK retries, and the retry arrives while the original transaction is still committing.
- Aggressive retry policy — very short backoff means several retries can pile onto a transaction that needs a few seconds.
- Two callers sharing one token — separate processes deliberately (or accidentally) issuing the same
ClientRequestTokenconcurrently.
How to fix it
Let the retries continue with exponential backoff — once the in-flight transaction completes, a retry with the same token returns success without applying the writes twice. Treat this exception as retryable.
Tune timeouts per the documented guidance so a retry can land after the transaction settles:
- allow at least one retry to be processed after 5 seconds have elapsed since the first attempt;
- set the per-request timeout to about 1 second or higher;
- keep the socket timeout slightly below the request timeout;
- use exponential backoff between attempts.
Don't rotate the token on retry — generating a fresh
ClientRequestTokenper attempt silently converts retries into new transactions (double-applying the writes). Same intent, same token, for up to 10 minutes:const token = randomUUID(); // one token per logical transaction await client.send(new TransactWriteItemsCommand({TransactItems, ClientRequestToken: token}));Serialize deliberate concurrent callers — if two workers can submit the same logical transaction, make one the owner or route both through a queue.
If transactions run long enough to trip timeouts, check what they're contending on — the DynoTable desktop app lets you inspect the items involved, and the DynamoDB pricing calculator shows what the doubled write capacity of transactional writes costs.
Related errors
- IdempotentParameterMismatchException — same token, different payload.
- TransactionCanceledException — the transaction itself failed.
- TransactionConflictException — item-level conflict with another transaction.
- Code example: TransactWriteItems in Node.js — shows ClientRequestToken usage.
- Learn: DynamoDB transactions
References
- TransactWriteItems — Amazon DynamoDB API Reference
- Amazon DynamoDB Transactions: How it works — Amazon DynamoDB Developer Guide
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
Last verified 2026-07-13 against the official AWS documentation linked above.