DynamoDB raises this error when your transaction or item-level write collides with another request touching the same key, so it rejects the new operation to keep the data consistent.
The TransactionConflictException is DynamoDB telling you that it could not obtain a lock on your primary key because another request already held it. Serializable isolation around transactions means that once one operation begins mutating an item, other operations that reference that same item—whether they are TransactWriteItems / TransactGetItems or even non-transactional PutItem, UpdateItem, or DeleteItem calls—will be rejected with this message instead of allowing both to proceed. The "Operation failed due to a conflict with another request" text is the service tracing which request claimed the partition first and why the new call cannot commit.
Start by looking at the TransactionConflict metric for the table and examine the CancellationReasons returned by the SDK so you understand which partition keys are involved.
\\\bash
aws cloudwatch get-metric-statistics \
--namespace "AWS/DynamoDB" \
--metric-name "TransactionConflict" \
--dimensions Name=TableName,Value=YourTableName \
--statistics Sum \
--start-time "$(date -u -d '10 minutes ago' +%Y-%m-%dT%H:%M:%SZ)" \
--end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--period 300 \
--region us-east-1
\\\
If you see CancellationReasons entries with Code=TransactionConflict (Java SDK gives a structured list, other languages include the same code in the error message), you know which item lost the race and can correlate it with the partition key in CloudWatch.
The conflict is retryable, but you must back off so all clients do not hammer the same key.
\\\`javascript
async function runTxn(params) {
for (let attempt = 0; attempt < 6; attempt++) {
try {
return await client.send(new TransactWriteCommand(params));
} catch (error) {
const isConflict =
error.name === 'TransactionConflictException' ||
(error.name === 'TransactionCanceledException' &&
error.CancellationReasons?.some(reason => reason.Code === 'TransactionConflict'));
if (!isConflict || attempt === 5) throw error;
const delay = Math.min(1000 * 2 ** attempt, 5000) + Math.random() * 100;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
\\\`
This spreads retries out and gives the transaction holding the partition time to finish before the next attempt runs.
Small, targeted transactions hold item locks for a shorter period. Split mega-transactions into separate operations when possible, and avoid batching unrelated partitions together. Also consider adding a lightweight lock record (with TTL) or staging queue so only one writer touches the hotspot at a time. When the conflict comes from non-transactional writes, move them into the same controlled transaction so DynamoDB can coordinate them atomically instead of letting each call grab the lock independently.
Use a condition expression to check a version counter or lock token before you commit, which lets you fail fast instead of enforcing the lock inside DynamoDB. For example:
\\\bash
aws dynamodb update-item \
--table-name YourTable \
--key '{ "pk": { "S": "user#123" } }' \
--update-expression "SET lockVersion = lockVersion + :one" \
--condition-expression "attribute_not_exists(lockVersion) OR lockVersion = :expected" \
--expression-attribute-values '{ ":one": { "N": "1" }, ":expected": { "N": "5" } }'
\\\
When the condition fails, you can hold off before trying again, which reduces the number of actions that ever make it far enough to trigger a TransactionConflictException.
Each TransactionConflictException increments the TransactionConflict CloudWatch metric for the table, so spikes there are the quickest way to spot a hotspot. When TransactWriteItems is involved, the resulting TransactionCanceledException contains CancellationReasons entries with Code=TransactionConflict that map directly to the item that lost the race. The exception can hit both transactional and non-transactional writes because DynamoDB does not let two operations modify the same item at the same time—it always fails the newcomer to guarantee serializability.
ValidationException: The provided key element does not match the schema
How to fix "ValidationException: The provided key element does not match the schema" in DynamoDB
UnrecognizedClientException: The security token included in the request is invalid
How to fix "UnrecognizedClientException: The security token included in the request is invalid" in DynamoDB
TransactionCanceledException: Transaction cancelled
How to fix "TransactionCanceledException: Transaction cancelled" in DynamoDB
RequestLimitExceeded: Throughput exceeds the current throughput limit for your account
How to fix "RequestLimitExceeded: Throughput exceeds the current throughput limit for your account" in DynamoDB
InternalServerError: Internal Server Error
How to fix "InternalServerError" in DynamoDB