apache/iceberg · error · NoSuchTableException

Table does not exist: ident

Error message

Table does not exist: ident

What it means

Thrown by SparkSessionCatalog.stageReplace (used by CREATE OR REPLACE TABLE) when the underlying session catalog's dropTable(ident) returns false, i.e. the table to be replaced does not exist. Iceberg treats REPLACE as requiring an existing table in this path, so the operation aborts before creating the new table.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkSessionCatalog.java:234

  @Override
  public StagedTable stageReplace(
      Identifier ident, StructType schema, Transform[] partitions, Map<String, String> properties)
      throws NoSuchNamespaceException, NoSuchTableException {
    String provider = properties.get("provider");
    TableCatalog catalog;
    if (useIceberg(provider)) {
      if (asStagingCatalog != null) {
        return asStagingCatalog.stageReplace(ident, schema, partitions, properties);
      }
      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, schema, partitions, properties);
      return new RollbackStagedTable(catalog, ident, table);

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

  @Override
  public StagedTable stageCreateOrReplace(
      Identifier ident, StructType schema, Transform[] partitions, Map<String, String> properties)
      throws NoSuchNamespaceException {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Create the table first if it doesn't exist (CREATE TABLE), or use CREATE TABLE IF NOT EXISTS semantics.
  2. Check the identifier/catalog routing: ensure the table exists in the catalog the statement targets (qualify with catalog name in SQL).
  3. List tables in the namespace (SHOW TABLES) to confirm exact name and namespace.
  4. If a stale catalog cache is involved, refresh the Spark catalog or restart the session.

Example fix

// before
spark.sql("CREATE OR REPLACE TABLE local.db.events AS SELECT ...");
// after
if (!spark.catalog().tableExists("local.db.events")) {
  spark.sql("CREATE TABLE local.db.events AS SELECT ...");
} else {
  spark.sql("CREATE OR REPLACE TABLE local.db.events AS SELECT ...");
}
Defensive patterns

Strategy: validation

Validate before calling

if (!spark.catalog().tableExists(identString)) { /* create instead of replace */ }

Try / catch

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

Prevention

When it happens

Trigger: Executing CREATE OR REPLACE TABLE via SparkSessionCatalog where the delegate session catalog's dropTable(ident) returns false — table absent in the session catalog; or the identifier resolves to a V1 session table path where drop is unsupported/failed.

Common situations: CREATE OR REPLACE TABLE on a table name that only exists in the main Iceberg catalog but the SQL routed to the session catalog (or vice versa); typos in table name; using REPLACE for migration when the table was never created; partition-transform confusion causing identifier mismatch.

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