apache/iceberg · error · NoSuchTableException

Table does not exist:

Error message

Table does not exist: 

What it means

In SparkSessionCatalog.stageReplace, a CREATE OR REPLACE requires dropping the existing table first; if catalog.dropTable returns false the table was not found and NoSuchTableException is thrown. This surfaces when you replace a table that does not exist in a context that requires it to exist.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkSessionCatalog.java:266

  }

  @Override
  public StagedTable stageReplace(Identifier ident, TableInfo tableInfo)
      throws NoSuchNamespaceException, NoSuchTableException {
    String provider = tableInfo.properties().get("provider");
    TableCatalog catalog;
    if (useIceberg(provider)) {
      if (asStagingCatalog != null) {
        return asStagingCatalog.stageReplace(ident, tableInfo);
      }
      catalog = icebergCatalog;
    } else {
      catalog = getSessionCatalog();
    }

    // attempt to drop the table and fail if it doesn't exist
    if (!catalog.dropTable(ident)) {
      throw new NoSuchTableException(ident);
    }

    try {
      // create the table with the session catalog, then wrap it in a staged table that will delete
      // to roll back
      Table table = catalog.createTable(ident, tableInfo);
      return new RollbackStagedTable(catalog, ident, table);

    } catch (TableAlreadyExistsException e) {
      // the table was deleted, but now already exists again. retry the replace.
      return stageReplace(ident, tableInfo);
    }
  }

  /**
   * @deprecated since 1.12.0, use {@link #stageCreateOrReplace(Identifier, TableInfo)} instead.
   */
  @Deprecated

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the fully qualified table name (catalog.namespace.table) exists with SHOW TABLES before REPLACE
  2. Use CREATE OR REPLACE semantics on the correct Iceberg catalog; or create the table first with CREATE TABLE
  3. Catch NoSuchTableException and fall back to CREATE TABLE AS SELECT instead of REPLACE

Example fix

// before
spark.sql("CREATE OR REPLACE TABLE spark_catalog.db.tbl AS SELECT ...");
// after
spark.sql("CREATE TABLE IF NOT EXISTS iceberg.db.tbl AS SELECT ... OR REPLACE if exists");
Defensive patterns

Strategy: validation

Validate before calling

// verify existence before CREATE OR REPLACE
if (!catalog.tableExists(ident)) {
  // create instead of replace
  catalog.createTable(ident, schema, spec);
}

Try / catch

try {
  spark.sql("CREATE OR REPLACE TABLE ...");
} catch (NoSuchTableException e) {
  spark.sql("CREATE TABLE ... AS SELECT ...");
}

Prevention

When it happens

Trigger: Executing CREATE OR REPLACE TABLE in the Spark session catalog path where the target table does not exist and dropTable(ident) returns false; race condition where another job dropped the table between existence check and stageReplace.

Common situations: REPLACE on a table name with a typo or wrong namespace; table exists in another catalog but not in the one being used; concurrent jobs where one drops the table while another replaces it.

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/2c66d6cddc006a60. Report an issue: GitHub.