apache/iceberg · error · NoSuchTableException

Cannot find source table '%s'

Error message

Cannot find source table '%s'

What it means

BaseTableCreationSparkAction's constructor loads the source table from the given Spark catalog; if Spark reports NoSuchTableException, it is rethrown as Iceberg's NoSuchTableException with the identifier. Create-table-like actions (snapshot/clone/migrate) require an existing source table.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/BaseTableCreationSparkAction.java:80

  private final String sourceTableLocation;
  private final TableCatalog sourceCatalog;
  private final Identifier sourceTableIdent;

  // Optional Parameters for destination
  private final Map<String, String> additionalProperties = Maps.newHashMap();

  BaseTableCreationSparkAction(
      SparkSession spark, CatalogPlugin sourceCatalog, Identifier sourceTableIdent) {
    super(spark);

    this.sourceCatalog = checkSourceCatalog(sourceCatalog);
    this.sourceTableIdent = sourceTableIdent;

    try {
      this.sourceTable = (V1Table) this.sourceCatalog.loadTable(sourceTableIdent);
      this.sourceCatalogTable = sourceTable.v1Table();
    } catch (org.apache.spark.sql.catalyst.analysis.NoSuchTableException e) {
      throw new NoSuchTableException("Cannot find source table '%s'", sourceTableIdent);
    } catch (ClassCastException e) {
      throw new IllegalArgumentException(
          String.format("Cannot use non-v1 table '%s' as a source", sourceTableIdent), e);
    }
    validateSourceTable();

    this.sourceTableLocation =
        CatalogUtils.URIToString(sourceCatalogTable.storage().locationUri().get());
  }

  protected abstract TableCatalog checkSourceCatalog(CatalogPlugin catalog);

  protected abstract StagingTableCatalog destCatalog();

  protected abstract Identifier destTableIdent();

  protected abstract Map<String, String> destTableProps();

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the source table exists: SHOW TABLES in the namespace or spark.catalog.tableExists
  2. Check the catalog and namespace parts of the identifier are correct
  3. Confirm you are connected to the intended catalog/metastore

Example fix

// before
CALL catalog.system.snapshot('prod.db.orders', 'db.orders_backup')
// after
CALL catalog.system.snapshot('prod.db.orders', 'db.orders_src') // ensure source ident resolves
Defensive patterns

Strategy: try-catch

Validate before calling

if (!spark.sessionState().catalogManager().catalog(sourceCatalogName).loadTable(ident) ...) // or spark.catalog.tableExists(db, table)

Type guard

boolean sourceExists(SparkSession spark, String db, String tbl) { return spark.catalog().tableExists(db, tbl); }

Try / catch

try { callAction(...); } catch (NoSuchTableException e) { LOG.error("Source table {} missing", sourceIdent, e); throw e; }

Prevention

When it happens

Trigger: Running snapshot / migrate / create-like Spark actions with a source identifier that doesn't exist in the source catalog — typo, wrong namespace, wrong catalog, or table dropped before the action.

Common situations: Migrating a Hive/Spark table whose name was mistyped; pointing at a catalog where the table was never created; case-sensitivity mismatches in identifiers.

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