apache/iceberg · error · NoSuchTableException

Cannot rename %s to %s. Table does not exist

Error message

Cannot rename %s to %s. Table does not exist

What it means

InMemoryCatalog.renameTable throws NoSuchTableException when the source table does not exist under 'from'. The rename reads the from entry from the internal tables map; a null location means no such table.

Source

Thrown at core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java:178

        .sorted(Comparator.comparing(TableIdentifier::toString))
        .collect(Collectors.toList());
  }

  @Override
  public void renameTable(TableIdentifier from, TableIdentifier to) {
    if (from.equals(to)) {
      return;
    }

    synchronized (this) {
      if (!namespaceExists(to.namespace())) {
        throw new NoSuchNamespaceException(
            "Cannot rename %s to %s. Namespace does not exist: %s", from, to, to.namespace());
      }

      String fromLocation = tables.get(from);
      if (null == fromLocation) {
        throw new NoSuchTableException("Cannot rename %s to %s. Table does not exist", from, to);
      }

      if (tables.containsKey(to)) {
        throw new AlreadyExistsException("Cannot rename %s to %s. Table already exists", from, to);
      }

      if (views.containsKey(to)) {
        throw new AlreadyExistsException("Cannot rename %s to %s. View already exists", from, to);
      }

      tables.put(to, fromLocation);
      tables.remove(from);
    }
  }

  @Override
  public void createNamespace(Namespace namespace) {
    createNamespace(namespace, Collections.emptyMap());

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the source exists via tableExists(from) before renaming
  2. Use the correct identifier including full namespace
  3. If it is a view, use the view rename path, not renameTable
  4. Catch NoSuchTableException to skip missing sources idempotently

Example fix

// before
catalog.renameTable(TableIdentifier.of("ns","evnts"), to);
// after
TableIdentifier from = TableIdentifier.of("ns","events");
if (catalog.tableExists(from)) {
  catalog.renameTable(from, to);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!catalog.tableExists(from)) { throw new IllegalStateException("Source table missing: " + from); }

Try / catch

try { catalog.renameTable(from, to); } catch (NoSuchTableException e) { log.warn("Skip rename, source missing: {}", from); }

Prevention

When it happens

Trigger: Calling catalog.renameTable(from, to) where from was never registered or was already dropped. Also when 'from' names a view rather than a table (views are stored separately).

Common situations: Renaming a table twice (second call fails); renaming a view via renameTable instead of the view API; case or namespace mismatch in the source identifier.

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/87b66a2e24738e42. Report an issue: GitHub.