DynamoDB: Table already exists

TL;DR — The operation wants to create its target table, and the name is already taken in this account + region. Restores (RestoreTableFromBackup / RestoreTableToPointInTime) throw TableAlreadyExistsException; CreateTable and ImportTable report the same situation as a ResourceInUseException. Pick a new target name — restores and imports can never write into an existing table.

What it means

TableAlreadyExistsException: A target table with the specified name already exists
ResourceInUseException: Table already exists: my-table

# what the engine actually returns, reproduced against DynamoDB Local:
ResourceInUseException: Cannot create preexisting table

Restore and import operations always create a brand-new table — they cannot merge into or overwrite a live one. If the target name resolves to any existing table (whatever its state) in the same account and region, the request fails up front. Which exception you see depends on the API: the restore family has its own TableAlreadyExistsException, while CreateTable and ImportTable surface the generic ResourceInUseException.

Why it happens

  • Restoring a backup over the original name — the natural instinct ("put my table back") collides with the still-existing table.
  • Re-running an import or IaC deployment — a retried ImportTable, or a CloudFormation/Terraform/CDK stack that tries to create a table which already exists outside the stack's state.
  • A create-then-retry race — the first CreateTable succeeded (or is still CREATING) and the retry finds the name taken.
  • Environment collision — two stages/environments share an account and both want the unprefixed name.

How to fix it

  1. Restore to a new name, then cut over — restore as my-table-restored, verify the data, repoint the application (or delete the old table and restore again under the original name once it's gone):

    aws dynamodb restore-table-from-backup \
      --target-table-name my-table-restored \
      --backup-arn arn:aws:dynamodb:...:table/my-table/backup/...
  2. If you intend to replace the table, delete the existing one first and wait until the deletion completes — the name stays taken while the table is in DELETING state (a restore attempted then fails with TableInUseException; see ResourceInUseException for the CreateTable side).

  3. For imports, choose an unused target name — ImportTable only creates new tables. To load data into an existing table, write it with BatchWriteItem/PutItem instead.

  4. For IaC retries, import the existing table into the stack's state (or rename), rather than fighting the create.

  5. Check what actually existsaws dynamodb list-tables in the same region/account settles whether the name is really free.

  6. Suffix restored tables with a date stamp (orders-20260812-restore) so cut-over and cleanup are unambiguous.

Measure in DynoTable

Before cut-over, open both the original and restored tables in DynoTable — switch with ⌘K and spot-check items side by side. Staging (⌘S) lets you test writes against the restored copy without touching production traffic.

Size the restored table with the pricing calculator. Switch accounts/Regions with ⌘P; Test Connection on Settings → Profiles. See Connect to AWS and Install.

Sources

References

Last verified 2026-07-13 against the official AWS documentation linked above.

Work with DynamoDB without the Console

A fast DynamoDB desktop client that runs the real SQL DynamoDB can’t — JOINs, GROUP BY, aggregates — with visual editing and an AI agent on your own Bedrock keys.

Free 30-day trial, no credit card — then the Free plan with no time limit.