DynamoDB Error Handling
Every database call can fail. Networks drop, tables hit capacity limits, and conditions fail. A well-built application expects errors, classifies them, and responds with the right action. Good error handling keeps users calm and data safe.
The Delivery Picture
A courier who finds a locked door has several choices. A closed shop means try again tomorrow. A wrong address means check the details. Each problem needs a different response. DynamoDB errors work the same way. Some deserve a retry, and others deserve a fix.
Two Error Families
| Family | HTTP Range | Meaning | Retry? |
|---|---|---|---|
| Client errors | 400 range | The request has a problem | Usually no, except throttling |
| Server errors | 500 range | DynamoDB had a temporary problem | Yes |
Common Errors and Responses
| Error | Cause | Action |
|---|---|---|
| ProvisionedThroughputExceededException | Requests exceeded provisioned capacity | Retry with backoff; raise capacity or fix hot keys |
| ThrottlingException | Too many control-plane or burst requests | Retry with backoff |
| ConditionalCheckFailedException | A condition expression returned false | Handle as a business result; do not retry blindly |
| ValidationException | Malformed request or invalid value | Fix the request |
| ResourceNotFoundException | Table or index does not exist | Check names and Region |
| ResourceInUseException | Table is still being created or deleted | Wait until the table is Active |
| TransactionCanceledException | A transaction failed a condition or conflicted | Read the cancellation reasons; retry on conflict only |
| ItemCollectionSizeLimitExceededException | An item collection passed 10 GB (tables with LSI) | Redesign keys |
| InternalServerError | Temporary service problem | Retry with backoff |
Retries with Exponential Backoff and Jitter
A retry sends the same request again after a short wait. The wait doubles after each failure, and a random value keeps thousands of clients from retrying in unison.
attempt = 0
WHILE attempt < max_attempts:
result = send_request()
IF result is success: STOP
IF error is not retryable: raise error
wait random(0, base_delay * 2 ^ attempt)
attempt = attempt + 1
raise error
The AWS SDKs include retry logic with sensible defaults. Adjust the maximum attempts and timeouts only when a measured need exists.
Diagram: Error Decision Flow
Request fails
│
├─ 500 range or throttling ──► Wait, retry with backoff
│
├─ ConditionalCheckFailed ───► Tell the user or apply business rule
│
├─ ValidationException ──────► Log, fix the code or input
│
└─ Unknown error ────────────► Log details, alert the team
Handling Failed Conditions
A failed condition is a normal outcome, not a fault. A stock update with the condition Stock >= 5 fails when stock is low. Catch the exception and show a message such as "Only 3 items left". Retrying the same request produces the same failure.
Safe Retries and Idempotency
An idempotent operation gives the same result when repeated. PutItem and DeleteItem behave idempotently. An increment such as SET Views = Views + 1 does not. A retry after a lost response can count twice.
- Attach a unique request ID to items and use a condition to reject duplicates.
- Pass a ClientRequestToken on transactions so repeated calls within 10 minutes do not run twice.
- Prefer designs where repeating a write leaves the data unchanged.
Timeouts and Network Failures
A timeout leaves the outcome unknown. The write may have succeeded before the connection broke. Design write paths so the application can check the item and learn the real state.
Batch and Partial Failures
Batch operations return UnprocessedItems or UnprocessedKeys instead of throwing an error. Check these fields after every batch call, and resend leftovers with backoff.
Logging and Alerting
- Log the error name, table, operation, and request ID.
- Track error counts with CloudWatch alarms.
- Keep user-facing messages short and friendly.
- Avoid writing sensitive item values into logs.
Summary
- Client errors need fixes, and server errors and throttling need retries.
- Exponential backoff with jitter protects DynamoDB and your application.
- A failed condition is a normal result that needs business handling.
- Idempotent design makes retries safe.
- Always inspect unprocessed items in batch responses.
