apache/iceberg · error · NoSuchTableException

Cannot rename table %s to %s: %s does not exist

Error message

Cannot rename table %s to %s: %s does not exist

What it means

DynamoDbCatalog.renameTable() validates that the source table exists before performing the rename; if the GetItem for the `from` key returns no item it throws NoSuchTableException with this message. A rename is implemented as read-source + write-new-key + delete-old-key, so the source row is mandatory.

Source

Thrown at aws/src/main/java/org/apache/iceberg/aws/dynamodb/DynamoDbCatalog.java:441

      throw e;
    }
  }

  @Override
  public void renameTable(TableIdentifier from, TableIdentifier to) {
    Map<String, AttributeValue> fromKey = tablePrimaryKey(from);
    Map<String, AttributeValue> toKey = tablePrimaryKey(to);

    GetItemResponse fromResponse =
        dynamo.getItem(
            GetItemRequest.builder()
                .tableName(awsProperties.dynamoDbTableName())
                .consistentRead(true)
                .key(fromKey)
                .build());

    if (!fromResponse.hasItem()) {
      throw new NoSuchTableException(
          "Cannot rename table %s to %s: %s does not exist", from, to, from);
    }

    GetItemResponse toResponse =
        dynamo.getItem(
            GetItemRequest.builder()
                .tableName(awsProperties.dynamoDbTableName())
                .consistentRead(true)
                .key(toKey)
                .build());

    if (toResponse.hasItem()) {
      throw new AlreadyExistsException(
          "Cannot rename table %s to %s: %s already exists", from, to, to);
    }

    fromResponse.item().entrySet().stream()
        .filter(e -> isProperty(e.getKey()))

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the source table exists with catalog.tableExists(from) before renaming.
  2. If a previous rename attempt may have partially succeeded, check whether the destination table already exists and skip the rename.
  3. Catch org.apache.iceberg.exceptions.NoSuchTableException and reconcile catalog state in retry logic.

Example fix

// before
catalog.renameTable(from, to);

// after
if (catalog.tableExists(from)) {
  catalog.renameTable(from, to);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!catalog.tableExists(from)) {
  throw new IllegalStateException("Source table " + from + " does not exist; cannot rename");
}
catalog.renameTable(from, to);

Try / catch

try {
  catalog.renameTable(from, to);
} catch (NoSuchTableException e) {
  // check whether a prior rename attempt moved the table already
  if (!catalog.tableExists(to)) throw e;
}

Prevention

When it happens

Trigger: Calling catalog.renameTable(from, to) when the source table's item is absent from the DynamoDB catalog table — the source was already dropped/renamed or `from` never existed.

Common situations: Concurrent renames where two jobs both move the same table and the second sees the source gone; renaming after a failed pipeline already dropped the table; wrong environment/identifier in migration scripts.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/15c5e30550f25353. Report an issue: GitHub.