apache/iceberg · error · java.lang.IllegalArgumentException

Cannot parse %s: %s

Error message

Cannot parse %s: %s

What it means

Spark3Util.catalogAndIdentifier(description, ...) parses an identifier string using Spark's parser and rethrows ParseException as IllegalArgumentException 'Cannot parse <description>: <name>'. The description (e.g. 'namespace' or 'identifier') indicates what failed to parse.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:776

      SparkSession spark, String name, CatalogPlugin defaultCatalog) throws ParseException {
    ParserInterface parser = spark.sessionState().sqlParser();
    Seq<String> multiPartIdentifier = parser.parseMultipartIdentifier(name).toIndexedSeq();
    List<String> javaMultiPartIdentifier = JavaConverters.seqAsJavaList(multiPartIdentifier);
    return catalogAndIdentifier(spark, javaMultiPartIdentifier, defaultCatalog);
  }

  public static CatalogAndIdentifier catalogAndIdentifier(
      String description, SparkSession spark, String name) {
    return catalogAndIdentifier(
        description, spark, name, spark.sessionState().catalogManager().currentCatalog());
  }

  public static CatalogAndIdentifier catalogAndIdentifier(
      String description, SparkSession spark, String name, CatalogPlugin defaultCatalog) {
    try {
      return catalogAndIdentifier(spark, name, defaultCatalog);
    } catch (ParseException e) {
      throw new IllegalArgumentException("Cannot parse " + description + ": " + name, e);
    }
  }

  public static CatalogAndIdentifier catalogAndIdentifier(
      SparkSession spark, List<String> nameParts) {
    return catalogAndIdentifier(
        spark, nameParts, spark.sessionState().catalogManager().currentCatalog());
  }

  /**
   * A modified version of Spark's LookupCatalog.CatalogAndIdentifier.unapply Attempts to find the
   * catalog and identifier a multipart identifier represents
   *
   * @param spark Spark session to use for resolution
   * @param nameParts Multipart identifier representing a table
   * @param defaultCatalog Catalog to use if none is specified
   * @return The CatalogPlugin and Identifier for the table
   */

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Quote problematic identifier parts with backticks and escape embedded backticks before passing the name
  2. Validate/sanitize the name (reject or escape reserved characters) before calling catalogAndIdentifier
  3. Call catalogAndIdentifier(List<String> nameParts) with pre-split parts to bypass the string parser entirely

Example fix

// before
Spark3Util.catalogAndIdentifier(spark, "my.table\"name", defaultCatalog); // throws
// after
Spark3Util.catalogAndIdentifier(spark, Arrays.asList("my", "table\"name"), defaultCatalog);
Defensive patterns

Strategy: validation

Validate before calling

if (!name.matches("[a-zA-Z0-9_.`]+")) throw new IllegalArgumentException("Invalid identifier: " + name);

Try / catch

try { return Spark3Util.catalogAndIdentifier(desc, spark, name, defaultCatalog); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Bad " + desc + " name: " + name, e); }

Prevention

When it happens

Trigger: Calling Spark3Util.catalogAndIdentifier(spark, name, defaultCatalog) (or the description overload) with a name that Spark's ParserInterface cannot parse — typically names with invalid characters, backticks misuse, or unbalanced quotes.

Common situations: Passing user-supplied table/namespace strings with special characters (dots, backticks, quotes) into procedures like CALL catalog.system.* actions or extension code that resolves identifiers.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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