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
- Pass a namespace-qualified Identifier (e.g. Identifier.of(new String[]{"db"}, "table")) instead of the PathIdentifier.
- 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.
- 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
- Never construct identifiers from raw user-supplied paths; qualify with catalog/namespace.
- Use Spark SQL identifiers (db.table) for mutations; reserve path strings for loadTable on path-qualified reads.
- Add an instanceof PathIdentifier check before every catalog extension call.
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
- Unsupported changelog scan task type:
- Unsupported command: ${command}
- Unknown time travel: ${timeTravel}
- Unsupported Spark view dependency: ${dependency.getClass().g
- Field + field.name() + not found in source schema
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/d8036b6b7a20ecd9.
Report an issue: GitHub.