apache/iceberg · error · NoSuchTableException
Table not found
Error message
Table not found: ${from} What it means
Thrown by SparkCatalog.renameTable when the underlying Iceberg catalog reports that the source table does not exist. Spark translates the Iceberg NoSuchTableException into Spark's org.apache.spark.sql.catalyst.analysis.NoSuchTableException carrying the original identifier. It means the rename's source identifier resolved to nothing in the catalog.
Solutions
- Verify the source table exists with 'SHOW TABLES IN <catalog>.<namespace>' or catalog.tableExists before renaming
- Check the identifier is fully qualified (namespace + name) and not a path identifier (starting with an absolute location)
- Confirm you are connected to the same catalog/warehouse that contains the table (check spark.sql.catalog.<name>.warehouse / type)
- Recreate or re-register the table if it was dropped
Example fix
// before
spark.sql("ALTER TABLE prod.events RENAME TO prod.events_archive")
// after
if (!spark.catalog().tableExists("prod", "events")) {
throw new IllegalStateException("Source table prod.events does not exist");
}
spark.sql("ALTER TABLE prod.events RENAME TO prod.events_archive") Defensive patterns
Strategy: validation
Validate before calling
if (!spark.catalog().tableExists(fromNamespace, fromName)) {
throw new IllegalArgumentException("Source table does not exist: " + from);
}
if (from instanceof PathIdentifier || to instanceof PathIdentifier) {
throw new IllegalArgumentException("renameTable does not support path identifiers");
} Type guard
boolean isRenameable(TableCatalog catalog, Identifier from, Identifier to) {
return catalog.tableExists(from) && !catalog.tableExists(to);
} Try / catch
try {
catalog.renameTable(from, to);
} catch (org.apache.spark.sql.catalyst.analysis.NoSuchTableException e) {
log.error("Rename failed, source table missing: {}", from, e);
throw new IllegalStateException("Cannot rename missing table " + from, e);
} Prevention
- Always qualify table names with catalog and namespace
- Check tableExists(from) before renaming
- Avoid path identifiers (tables loaded by location) for renames
- Pin catalog warehouse config so all jobs point at the same metastore
When it happens
Trigger: Calling ALTER TABLE ... RENAME TO or SparkCatalog.renameTable(from, to) where 'from' is not a table in the catalog: the table was dropped, the name is misspelled or wrongly qualified, or a path identifier (a table loaded by 'spark_catalog.<path>') is passed since path identifiers are rejected.
Common situations: Renaming a table in a different namespace than assumed (missing qualifier), using a session catalog that points at a different warehouse than where the table lives, typos in table names, or attempting to rename a path-based table.
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
- Cannot find source table
- Couldn't load table ' ' in catalog
- Couldn't load table ' ' in catalog
- NoSuchTableException(from)
- NoSuchTableException(ident)
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8ef39e7179177693.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:409
}
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)