---
cuppy_hub: aws
cuppy_path: reference/dynamodb/errors.md
cuppy_section: docs
cuppy_doc: 2HVP-R0RX
cuppy_doc_uuid: 413c490f-cec8-4626-9172-bcfcf8885001
cuppy_permalink: https://cuppy.io/aws/d/2HVP-R0RX
cuppy_version: 4
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/aws/docs/reference/dynamodb/errors
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 465ffc554709f1c5a5191f7ea42cf22f87dcf1ff1f359625c66fad9e96f3a053
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Amazon DynamoDB errors

**The SDKs already retry the retryable errors with exponential backoff.** If one reaches your code, the rate is too high for the table or account, or the request itself is wrong. Never blindly retry a 4xx other than the throttling ones.

| Exception (HTTP 400 unless noted) | Retry? | Meaning → fix | Check |
|---|---|---|---|
| `ProvisionedThroughputExceededException` | Yes, slower | A provisioned table or GSI is over its throughput. Back off; raise capacity, switch to on-demand, or spread keys | `ThrottledRequests` and consumed vs provisioned capacity for the table **and each GSI** in CloudWatch at that minute; `aws dynamodb describe-table --table-name <t>` → `BillingModeSummary` |
| `ThrottlingException` | Yes, slower | The request rate is too high: control-plane calls too fast, or a high on-demand data-plane rate | Which call failed: control-plane (`CreateTable`, `UpdateTable`, …) vs data-plane. CloudTrail `errorCode` for control-plane bursts |
| `RequestLimitExceeded` | Yes, slower | Throughput exceeds the **account** limit; an on-demand table can't scale further. Request a quota increase (Service Quotas) | `aws dynamodb describe-limits` against the account's consumed throughput; Service Quotas for the live account value |
| `ConditionalCheckFailedException` | **No** | Your `ConditionExpression` was false. That is the expected outcome of an optimistic or conditional write: handle it as business logic | Read the item (`get-item --consistent-read`) and evaluate the `ConditionExpression` against it; add `ReturnValuesOnConditionCheckFailure: ALL_OLD` to see the item that failed |
| `ValidationException` | No | Malformed request: missing or out-of-range parameter, type mismatch, a reserved word not aliased, key schema mismatch, or a constraint exceeded (item over 400 KB, expression over 4 KB, more than 100 `IN` values, more than 100 transaction items) | The message names the parameter. Compare the key attributes and types with `describe-table` → `KeySchema`/`AttributeDefinitions` |
| `ItemCollectionSizeLimitExceededException` | Yes, after fixing | A partition key's item collection passed **10 GB** on a table with an LSI. Redesign keys (an LSI can't be removed) | `describe-table` shows `LocalSecondaryIndexes`; the error only occurs on tables that have one |
| `LimitExceededException` | Yes | Too many concurrent control-plane operations: more than 500 tables and indexes in CREATING, DELETING or UPDATING | `aws dynamodb list-tables` + `describe-table` → `TableStatus` for tables in CREATING, UPDATING or DELETING |
| `ResourceNotFoundException` | No | Wrong table name or Region, or the table is still too early in CREATING. Wait with `aws dynamodb wait table-exists` | `aws dynamodb describe-table --table-name <t> --region <r>`: does it exist in **this** account and Region, and is `TableStatus` ACTIVE? |
| `ResourceInUseException` | No | Creating a table that exists, or deleting one still CREATING | `describe-table` → `TableStatus` |
| `AccessDeniedException` | No | The request wasn't correctly signed (the error page's wording). Also the usual name for an IAM or KMS denial (UNVERIFIED that IAM denials use this name; check the message for `is not authorized to perform`) → `guides/iam/fix-access-denied.md` | Message contains `is not authorized to perform` → IAM/KMS denial; otherwise signing. `aws sts get-caller-identity` with the same credentials |
| `UnrecognizedClientException` | No (fix keys) | Access key ID or session token invalid. Usually expired or wrong-account credentials (`reference/sts/errors.md`) | `aws sts get-caller-identity` with the same credentials; check the session token's expiry |
| `MissingAuthenticationTokenException` / `IncompleteSignatureException` | No | Missing or malformed authorization header. Usually a hand-built request, not SDK use | Only if not using an SDK: inspect the request's `Authorization` header |
| `ReplicatedWriteConflictException` | Yes | Multi-Region strongly consistent global tables: another Region is writing the same item | `describe-table` → `MultiRegionConsistency` is `STRONG`; look for concurrent writers to that key in other Regions (the field name is from the API model) |
| `TransactionCanceledException` | Depends | A transaction failed. Its cancellation reasons say which item and why, for example a condition. The exception carries `CancellationReasons`, one entry per item in request order (member name from the API model; the per-item order is the hub's reading) | Read `CancellationReasons`: each entry has a `Code` (for example `ConditionalCheckFailed`) for the item at that position |
| `InternalServerError` (500) / `ServiceUnavailable` (503) | Yes | Server side. **A write may have succeeded**: retry `TransactWriteItems` freely, but for `PutItem`/`UpdateItem`/`DeleteItem` read the item first or make the write conditional | Read the item back before retrying a non-idempotent write |

## Not errors, but often treated as one

- **`UnprocessedItems` / `UnprocessedKeys`** in batch responses are partial successes. Resubmit those with backoff.
- **`LastEvaluatedKey`** in a Query or Scan response means there are more pages (1 MB per call). It isn't truncation.
- **Empty `Item`** from `GetItem` means the item doesn't exist. No error is raised.

## Finding the hot key

Sustained throttling on part of a table usually means writes or reads concentrate on a few partition key values. CloudWatch Contributor Insights for DynamoDB shows the most-accessed keys. Turn it on with `aws dynamodb update-contributor-insights --table-name <t> --contributor-insights-action ENABLE` (operation from the API model). The fix is a key design that spreads load (`guides/dynamodb/design-and-access.md`).

## When none of these fits

Keep the request ID from the SDK error and the table's CloudWatch metrics for the minute it happened: `ThrottledRequests`, consumed versus provisioned capacity, and per-index metrics. Search the hub for the exact message. For conditional-write surprises, read the item and compare it with the `ConditionExpression`. If a global table is involved, check which Region wrote last (`reference/dynamodb/ttl-pitr-and-global-tables.md`).


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 131 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/aws/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
