ResourceInUseException
AWS ResourceInUseException means the requested DynamoDB operation cannot be performed because the target table or index is currently being created, updated, or deleted. The resource is in a transitional state that does not accept the requested change.
Last reviewed: March 20, 2026|Editorial standard: source-backed technical guidance
What Does Resource In Use Mean?
ResourceInUseException signals a state conflict at the DynamoDB resource level - the table exists but is not in ACTIVE state and cannot accept schema changes, index modifications, or deletion requests. Unlike ResourceNotFoundException which means the table is absent, ResourceInUseException means the table is present but temporarily locked in a lifecycle transition.
Common Causes
- -CreateTable is called for a table that already exists and is currently in CREATING state - DynamoDB rejects the duplicate creation request with ResourceInUseException.
- -UpdateTable is called to add a Global Secondary Index while the table is still processing a previous index creation or deletion, because DynamoDB only allows one GSI change at a time.
- -DeleteTable is called immediately after CreateTable before the table reaches ACTIVE state, so the delete request is rejected because the table is still initializing.
How to Fix Resource In Use
- 1Call DescribeTable and check the TableStatus field - wait until it returns ACTIVE before issuing CreateTable, UpdateTable, or DeleteTable operations.
- 2For GSI changes, check the IndexStatus of all existing indexes in the DescribeTable response - wait until all indexes are ACTIVE before adding or removing another index.
- 3Use AWS SDK waiters - wait_until_table_exists and wait_until_table_not_exists - to automatically poll table state rather than implementing manual polling loops.
Step-by-Step Diagnosis for Resource In Use
- 1Call DescribeTable on the affected table and inspect TableStatus - valid terminal states are ACTIVE and DELETING; CREATING and UPDATING indicate a transition in progress.
- 2Check the GlobalSecondaryIndexes array in DescribeTable for any index with IndexStatus other than ACTIVE - a single non-ACTIVE index blocks all further schema changes.
- 3Review recent table operations in CloudTrail to identify what triggered the current transitional state and estimate how long the transition has been running.
- 4Confirm the operation being attempted - CreateTable, UpdateTable, or DeleteTable - and verify it is appropriate for the current table state.
Table and Index State Validation
- -Check TableStatus in DescribeTable before any schema operation - CREATING means a CreateTable call is still in progress and can take up to several minutes for large tables with multiple GSIs (example: infrastructure-as-code tool calls CreateTable and immediately calls UpdateTable to add a tag, receiving ResourceInUseException because the table has not reached ACTIVE).
- -Inspect each GlobalSecondaryIndexes entry for IndexStatus - DynamoDB processes one GSI change at a time and CREATING or DELETING on any index blocks additional UpdateTable calls (example: adding a second GSI while the first is still in CREATING state returns ResourceInUseException even though the table itself is ACTIVE).
Infrastructure-as-Code and Migration Timing
- -Check whether the ResourceInUseException is coming from an infrastructure tool like Terraform, CDK, or CloudFormation that is applying multiple DynamoDB changes in parallel - these tools sometimes issue concurrent table operations that DynamoDB rejects (example: Terraform plan includes both a GSI addition and a table tag update applied simultaneously).
- -For database migration scripts that create tables and immediately populate them, add an explicit ACTIVE state check between CreateTable and the first PutItem or BatchWriteItem call - DynamoDB accepts writes only when the table is in ACTIVE state (example: migration script calls CreateTable then immediately calls BatchWriteItem, receiving ResourceInUseException for the first few seconds).
Implementation Examples
# Check table status before making changes
aws dynamodb describe-table \
--table-name my-table \
--query '{TableStatus: Table.TableStatus, IndexStatuses: Table.GlobalSecondaryIndexes[*].{Name: IndexName, Status: IndexStatus}}'
# Ready output:
# { "TableStatus": "ACTIVE", "IndexStatuses": [{"Name": "gsi-1", "Status": "ACTIVE"}] }
# Blocked output:
# { "TableStatus": "ACTIVE", "IndexStatuses": [{"Name": "gsi-1", "Status": "CREATING"}] }import { DynamoDBClient, DescribeTableCommand, UpdateTableCommand } from '@aws-sdk/client-dynamodb';
import { waitUntilTableExists } from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({ region: 'us-east-1' });
async function waitForActiveTable(tableName) {
await waitUntilTableExists(
{ client, maxWaitTime: 300 },
{ TableName: tableName }
);
// Also wait for all GSIs to reach ACTIVE
let ready = false;
while (!ready) {
const { Table } = await client.send(new DescribeTableCommand({ TableName: tableName }));
ready = Table.GlobalSecondaryIndexes?.every(gsi => gsi.IndexStatus === 'ACTIVE') ?? true;
if (!ready) await new Promise(r => setTimeout(r, 5000));
}
}
await waitForActiveTable('my-table');
await client.send(new UpdateTableCommand({ /* GSI change */ }));import boto3
import time
client = boto3.client('dynamodb', region_name='us-east-1')
def wait_for_active(table_name, timeout=300):
start = time.time()
while time.time() - start < timeout:
response = client.describe_table(TableName=table_name)
table = response['Table']
table_active = table['TableStatus'] == 'ACTIVE'
gsi_active = all(
gsi['IndexStatus'] == 'ACTIVE'
for gsi in table.get('GlobalSecondaryIndexes', [])
)
if table_active and gsi_active:
return
time.sleep(5)
raise TimeoutError(f'Table {table_name} did not reach ACTIVE state')
wait_for_active('my-table')
client.update_table(TableName='my-table', GlobalSecondaryIndexUpdates=[...])How to Verify the Fix
- -Call DescribeTable and confirm TableStatus is ACTIVE and all GlobalSecondaryIndexes show IndexStatus ACTIVE before re-attempting the operation.
- -Re-run the CreateTable, UpdateTable, or DeleteTable call and confirm it completes without ResourceInUseException.
- -For GSI changes, verify the new index appears in DescribeTable with IndexStatus ACTIVE and begins serving queries correctly.
How to Prevent Recurrence
- -Add DescribeTable state checks to all infrastructure scripts and migration tools so DynamoDB operations only proceed when the table and all indexes are in ACTIVE state.
- -Use AWS SDK waiters for DynamoDB table operations - they handle polling automatically and raise an exception if the table does not reach the expected state within a configurable timeout.
- -Serialize GSI modifications in migration scripts - apply one index change at a time and wait for ACTIVE state before applying the next, rather than batching all schema changes in a single UpdateTable call.
Pro Tip
- -when creating a DynamoDB table with multiple GSIs, include all indexes in the initial CreateTable call rather than adding them via subsequent UpdateTable calls - creating all GSIs together is faster, avoids ResourceInUseException between index additions, and reduces the total time before the table is ready for writes.
Decision Support
Compare Guide
HTTP 400 vs 422: Bad Request vs Unprocessable Content
Fix API payload issues faster by using 400 for malformed syntax and 422 for semantic validation failures, so clients correct format before business rules.
Playbook
CORS Error Fix Playbook (Preflight / Origin / Credentials)
Use this playbook to separate browser-enforced cross-origin policy failures from server-side CORS header and route defects and apply strict origin and credential controls safely.
Playbook
Validation Failure Playbook (400 / 422 / INVALID_ARGUMENT)
Use this playbook to separate malformed-request failures from semantic validation failures, then fix request contracts without broad server-side bypasses.
Official References
Provider Context
This guidance is specific to AWS services. Always validate implementation details against official provider documentation before deploying to production.