apache/iceberg · error · org.apache.spark.sql.catalyst.analysis.NoSuchTableException

NoSuchTableException

Error message

NoSuchTableException: <from>

What it means

renameTable delegates to the Iceberg catalog; when the source table cannot be found, the Iceberg NoSuchTableException is translated into Spark's NoSuchTableException carrying the source identifier. The rename never starts because the 'from' table does not exist in this catalog.

Solutions

  1. Confirm the source table exists via SHOW TABLES in the same catalog
  2. Check that the statement runs against the correct spark catalog plugin
  3. Correct the source identifier spelling/casing
  4. Guard with an existence check before renaming

Example fix

// before
spark.sql("ALTER TABLE db.orders RENAME TO db.orders_archive") // table absent
// after
if (spark.catalog().tableExists("db.orders")) { spark.sql("ALTER TABLE db.orders RENAME TO db.orders_archive"); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (!spark.catalog().tableExists(fromIdent)) { return; }

Try / catch

try { spark.sql("ALTER TABLE db.t RENAME TO db.t2"); } catch (NoSuchTableException e) { /* source missing: handle */ }

Prevention

When it happens

Trigger: ALTER TABLE ... RENAME TO where the source identifier is misspelled, was dropped, or resolves to a different catalog/namespace than expected.

Common situations: Rename across sessions/catalogs; case-sensitive identifier mismatch; concurrent drop by another job before the rename.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:381

  }

  private boolean catalogDropTable(Identifier ident) {
    if (isPathIdentifier(ident)) {
      return tables.dropTable(((PathIdentifier) ident).location(), false /* don't purge data */);
    } else {
      return icebergCatalog.dropTable(buildIdentifier(ident), false /* don't purge data */);
    }
  }

  @Override
  public void renameTable(Identifier from, Identifier to)
      throws NoSuchTableException, TableAlreadyExistsException {
    try {
      checkNotPathIdentifier(from, "renameTable");
      checkNotPathIdentifier(to, "renameTable");
      icebergCatalog.renameTable(buildIdentifier(from), buildIdentifier(to));
    } catch (org.apache.iceberg.exceptions.NoSuchTableException e) {
      throw new NoSuchTableException(from);
    } catch (AlreadyExistsException e) {
      throw new TableAlreadyExistsException(to);
    }
  }

  @Override
  public void invalidateTable(Identifier ident) {
    if (!isPathIdentifier(ident)) {
      icebergCatalog.invalidateTable(buildIdentifier(ident));
    }
  }

  @Override
  public Identifier[] listTables(String[] namespace) {
    return icebergCatalog.listTables(Namespace.of(namespace)).stream()
        .map(ident -> Identifier.of(ident.namespace().levels(), ident.name()))
        .toArray(Identifier[]::new);
  }

View on GitHub (pinned to 86d9c8fc54)