apache/iceberg · error · NoSuchTableException
Cannot find source table %s
Error message
Cannot find source table %s
What it means
MigrateTableSparkAction backs up the source table by renaming it (destCatalog().renameTable(sourceTableIdent(), backupIdent)). Spark's catalog threw NoSuchTableException, so the action rethrows it as Iceberg's NoSuchTableException 'Cannot find source table %s' — the table you asked to migrate does not exist in the destination catalog.
Source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/actions/MigrateTableSparkAction.java:239
@Override
protected TableCatalog checkSourceCatalog(CatalogPlugin catalog) {
// currently the import code relies on being able to look up the table in the session catalog
Preconditions.checkArgument(
catalog instanceof SparkSessionCatalog,
"Cannot migrate a table from a non-Iceberg Spark Session Catalog. Found %s of class %s as the source catalog.",
catalog.name(),
catalog.getClass().getName());
return (TableCatalog) catalog;
}
private void renameAndBackupSourceTable() {
try {
LOG.info("Renaming {} as {} for backup", sourceTableIdent(), backupIdent);
destCatalog().renameTable(sourceTableIdent(), backupIdent);
} catch (org.apache.spark.sql.catalyst.analysis.NoSuchTableException e) {
throw new NoSuchTableException("Cannot find source table %s", sourceTableIdent());
} catch (org.apache.spark.sql.catalyst.analysis.TableAlreadyExistsException e) {
throw new AlreadyExistsException(
"Cannot rename %s as %s for backup. The backup table already exists.",
sourceTableIdent(), backupIdent);
}
}
private void restoreSourceTable() {
try {
LOG.info("Restoring {} from {}", sourceTableIdent(), backupIdent);
destCatalog().renameTable(backupIdent, sourceTableIdent());
} catch (org.apache.spark.sql.catalyst.analysis.NoSuchTableException e) {
LOG.error(
"Cannot restore the original table, the backup table {} cannot be found", backupIdent, e);
} catch (org.apache.spark.sql.catalyst.analysis.TableAlreadyExistsException e) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Verify the table exists: run SHOW TABLES IN <catalog>.<db> or spark.catalog.tableExists("catalog.db.table") with the exact identifier used in migrate().
- Check the identifier's case and case-sensitivity setting (spark.sql.caseSensitive) and quoting.
- Confirm the Spark session is configured for the catalog you expect (spark.sql.catalog.<name> entries) and that you are not silently hitting spark_default.
- Re-run the migration after creating/restoring the missing source table.
Example fix
// before
spark.sql("CALL prod_catalog.system.migrate(table => 'events')");
// after
spark.sql("CALL prod_catalog.system.migrate(table => 'analytics.events')"); // fully-qualified, verified via SHOW TABLES Defensive patterns
Strategy: validation
Validate before calling
// Scala / SQL pre-check before migrate val ident = "prod_catalog.analytics.events" if (!spark.catalog.tableExists(ident)) throw new IllegalArgumentException(s"Source table $ident does not exist")
Try / catch
try {
SparkActions.get(spark).migrateTable(ident).execute();
} catch (org.apache.iceberg.exceptions.NoSuchTableException e) {
LOG.error("Verify identifier '{}' exists in the target catalog", ident, e);
} Prevention
- Always use fully-qualified three-part identifiers in CALL migrate/rewrite procedures.
- Run SHOW TABLES IN <catalog>.<db> immediately before migrating.
- Check spark.sql.catalog.* configuration matches the catalog name used in the identifier.
When it happens
Trigger: CALL spark_catalog.system.migrate(...) or SparkActions.get(spark).migrateTable(ident) where the source identifier is misspelled, the table lives in a different catalog/database, or the catalog lookup fails before the migration starts.
Common situations: Wrong three-part identifier, running against the wrong Spark session/catalog config, case sensitivity mismatch (spark.sql.caseSensitive), or the table being dropped by another process just before migration.
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
- No such table: %s
- No such table: %s
- Table does not exist:
- Table does not exist: %s
- Invalid table identifier: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/cfc5ac5e8e5f7b5f.
Report an issue: GitHub.