apache/iceberg · error · org.apache.iceberg.exceptions.NoSuchTableException
Cannot find source table
Error message
Cannot find source table %s
What it means
MigrateTableSparkAction first renames the source table to a backup identifier before creating the new Iceberg table in its place. If destCatalog().renameTable throws Spark's NoSuchTableException (the source vanished between load and rename), it is converted into Iceberg's NoSuchTableException with this message.
Solutions
- Verify the source table still exists: SHOW TABLES / DESCRIBE the identifier
- Re-run the MIGRATE procedure once no concurrent jobs touch the source table
- Check that the identifier resolves against the intended catalog (spark_catalog for the legacy source)
Example fix
// before
CALL iceberg.system.migrate('db.src_tbl') -- src_tbl dropped concurrently
// after
SHOW TABLES IN db; -- confirm src_tbl exists
CALL iceberg.system.migrate('db.src_tbl'); Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the source exists and is quiescent before migrating
spark.sql("DESCRIBE TABLE db.src_tbl"); Try / catch
try { migrateAction.execute(); } catch (NoSuchTableException e) { /* source disappeared: verify identifier, re-create or re-run when stable */ } Prevention
- Ensure no concurrent jobs drop or rename the source table during migration
- Verify the identifier and catalog resolution before running MIGRATE
- Re-run MIGRATE after transient concurrency issues; the action restores state on failure
When it happens
Trigger: Calling MIGRATE and the source table is dropped by another session between action initialization and renameAndBackupSourceTable; wrong source identifier resolution in the destination catalog.
Common situations: Concurrent drop/overwrite of the source table; case-sensitive identifier mismatch causing renameTable to resolve a different catalog; a failed earlier migrate run left inconsistent catalog state.
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
- Cannot find source table
- Cannot rename as for backup. The backup table already…
- NoSuchTableException(from)
- NoSuchTableException
- Cannot find source table
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/d9ef9db81d37c19a.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.2/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)