apache/iceberg · error · org.apache.iceberg.exceptions.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 catalog; if Spark reports NoSuchTableException, the action rethrows Iceberg's NoSuchTableException with the identifier. The action cannot proceed without a concrete source V1 table.

Source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/actions/BaseTableCreationSparkAction.java:81

  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 catalog.ns and correct the identifier
  2. Confirm the catalog and namespace in the procedure call match the actual location
  3. Check current catalog/session settings and use a fully qualified identifier

Example fix

// before
CALL cat.system.snapshot('spark_catalog.db.tableA', 'iceberg.db.tableA');
// after
CALL cat.system.snapshot('spark_catalog.db.table_a', 'iceberg.db.table_a');
Defensive patterns

Strategy: try-catch

Validate before calling

// verify existence before the call
Dataset<Row> tables = spark.sql("SHOW TABLES IN " + namespace);
assert tables.filter("tableName = '" + name + "'").count() == 1 : "source table missing";

Try / catch

try { catalog.loadTable(ident); }
catch (org.apache.iceberg.exceptions.NoSuchTableException e) {
  // correct identifier or create/restore the table
  throw new IllegalArgumentException("Check source identifier: " + ident, e);
}

Prevention

When it happens

Trigger: Running snapshot/migrate/inherit actions (e.g. CALL catalog.system.snapshot(...)) where the source identifier is misspelled, does not exist, or is not visible in the current namespace/catalog.

Common situations: Typos in table name or namespace, wrong current catalog/session catalog, table dropped concurrently, or case-sensitivity mismatches in identifier resolution.

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