apache/iceberg · error · IllegalArgumentException

Cannot pass path based identifier to %s method. %s is a path

Error message

Cannot pass path based identifier to %s method. %s is a path.

What it means

SparkCatalog distinguishes table names (namespace-qualified identifiers) from file paths (PathIdentifier, produced when an identifier looks like a location such as '/path/to/table' or 'file:/...'). checkNotPathIdentifier throws this IllegalArgumentException when an API method that only accepts named identifiers is given a path. The message names the offending method and the path that was passed.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:889

    if (!propertyChanges.isEmpty()) {
      Spark3Util.applyPropertyChanges(transaction.updateProperties(), propertyChanges).commit();
    }

    if (!schemaChanges.isEmpty()) {
      Spark3Util.applySchemaChanges(transaction.updateSchema(), schemaChanges).commit();
    }

    transaction.commitTransaction();
  }

  private static boolean isPathIdentifier(Identifier ident) {
    return ident instanceof PathIdentifier;
  }

  private static void checkNotPathIdentifier(Identifier identifier, String method) {
    if (identifier instanceof PathIdentifier) {
      throw new IllegalArgumentException(
          String.format(
              "Cannot pass path based identifier to %s method. %s is a path.", method, identifier));
    }
  }

  private Table load(Identifier ident, TimeTravel timeTravel) throws NoSuchTableException {
    if (isPathIdentifier(ident)) {
      return loadPath((PathIdentifier) ident, timeTravel);
    }

    try {
      org.apache.iceberg.Table table = icebergCatalog.loadTable(buildIdentifier(ident));
      return SparkTable.create(table, timeTravel);

    } catch (org.apache.iceberg.exceptions.NoSuchTableException e) {
      if (ident.namespace().length == 0) {
        throw new NoSuchTableException(ident);
      }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Pass a namespace-qualified Identifier (e.g. Identifier.of(new String[]{"db"}, "table")) instead of the PathIdentifier.
  2. If you only have a file path, use the path-based API on purpose: loadTable with PathIdentifier is allowed for load, so restrict path usage to load/exists paths, or use HadoopTables directly with the location.
  3. Before calling, check `ident instanceof PathIdentifier` and branch to the correct code path (loadPath semantics) rather than a named-catalog mutation method.

Example fix

// before
catalog.createTable(pathIdent, schema, spec); // throws

// after
if (ident instanceof org.apache.iceberg.spark.PathIdentifier) {
  throw new IllegalArgumentException("Use a named identifier for createTable");
}
catalog.createTable(Identifier.of(new String[]{"db"}, "table"), schema, spec);
Defensive patterns

Strategy: type-guard

Validate before calling

// resolve identifiers from SQL text first, then validate
if (ident instanceof org.apache.iceberg.spark.PathIdentifier) {
  throw new IllegalArgumentException("Path identifiers are not valid for method " + methodName);
}

Type guard

boolean isNamedIdentifier(CatalogPlugin.Identifier ident) {
  return !(ident instanceof org.apache.iceberg.spark.PathIdentifier);
}

Try / catch

try {
  catalog.createTable(ident, schema, spec);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Cannot pass path based identifier")) {
    throw new IllegalArgumentException("Provide a db.table identifier, not a file path");
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling SparkCatalog methods like createTable, stageReplace, loadNamespaceMetadata, or other entry points that guard with checkNotPathIdentifier(ident, "<method>") while the Identifier is a PathIdentifier — e.g. calling catalog.createTable on a path-style identifier obtained from parsing a location string.

Common situations: Programmatic use of the Iceberg Spark catalog extension where an identifier was resolved from a table location; passing a file path where a SQL name is required; a customer-side helper building identifiers from user input that contains '/'.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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