apache/iceberg · error · AlreadyExistsException

Cannot rename %s because destination table %s exists

Error message

Cannot rename %s because destination table %s exists

What it means

EcsCatalog.renameTable throws AlreadyExistsException when the destination table identifier already exists as an object in ECS. Rename refuses to overwrite an existing table silently; drop or rename the destination away first.

Source

Thrown at dell/src/main/java/org/apache/iceberg/dell/ecs/EcsCatalog.java:244

    return new EcsURI(
        String.format("%s/%s%s", namespacePrefix(id.namespace()), id.name(), TABLE_OBJECT_SUFFIX));
  }

  /**
   * Table rename will only move table object, the data objects will still be in-place.
   *
   * @param from identifier of the table to rename
   * @param to new table name
   */
  @Override
  public void renameTable(TableIdentifier from, TableIdentifier to) {
    if (!namespaceExists(to.namespace())) {
      throw new NoSuchNamespaceException(
          "Cannot rename %s to %s because namespace %s does not exist", from, to, to.namespace());
    }

    if (tableExists(to)) {
      throw new AlreadyExistsException(
          "Cannot rename %s because destination table %s exists", from, to);
    }

    EcsURI fromURI = tableURI(from);
    if (!objectMetadata(fromURI).isPresent()) {
      throw new NoSuchTableException("Cannot rename table because table %s does not exist", from);
    }

    Properties properties = loadProperties(fromURI);
    EcsURI toURI = tableURI(to);

    if (!putNewProperties(toURI, properties.content())) {
      throw new AlreadyExistsException(
          "Cannot rename %s because destination table %s exists", from, to);
    }

    client.deleteObject(fromURI.bucket(), fromURI.name());
    LOG.info("Rename table {} to {}", from, to);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Drop or rename the existing destination table before retrying.
  2. Use a different target table name.
  3. Check catalog.tableExists(to) before renaming and handle the conflict explicitly.

Example fix

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

Strategy: validation

Validate before calling

if (catalog.tableExists(to)) { throw new IllegalStateException("Destination exists: " + to); }

Try / catch

try {
  catalog.renameTable(from, to);
} catch (AlreadyExistsException e) {
  LOG.error("Destination {} already exists", to, e);
}

Prevention

When it happens

Trigger: Calling catalog.renameTable(from, to) where tableExists(to) is true — a properties object exists at the destination table URI.

Common situations: Retrying a partially completed rename that already copied properties to the destination; renaming over an existing table by accident; concurrent jobs renaming to the same target.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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