apache/iceberg · error · IllegalArgumentException

Invalid session catalog: ${sparkSessionCatalog}

Error message

Invalid session catalog: ${sparkSessionCatalog}

What it means

setDelegateCatalog requires the plugin supplied as the Spark session catalog to be simultaneously a TableCatalog, FunctionCatalog, and SupportsNamespaces. If the configured SparkSessionCatalog plugin lacks any of these interfaces, an IllegalArgumentException 'Invalid session catalog' is thrown, since Iceberg's session-catalog delegation cannot function without all three capabilities.

Source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkSessionCatalog.java:438

      return;
    }

    Preconditions.checkArgument(
        catalogHmsUri.equals(envHmsUri),
        "Inconsistent Hive metastore URIs: %s (Spark session) != %s (spark_catalog)",
        envHmsUri,
        catalogHmsUri);
  }

  @Override
  @SuppressWarnings("unchecked")
  public void setDelegateCatalog(CatalogPlugin sparkSessionCatalog) {
    if (sparkSessionCatalog instanceof TableCatalog
        && sparkSessionCatalog instanceof FunctionCatalog
        && sparkSessionCatalog instanceof SupportsNamespaces) {
      this.sessionCatalog = (T) sparkSessionCatalog;
    } else {
      throw new IllegalArgumentException("Invalid session catalog: " + sparkSessionCatalog);
    }
  }

  @Override
  public String name() {
    return catalogName;
  }

  private boolean useIceberg(String provider) {
    if (provider == null || "iceberg".equalsIgnoreCase(provider)) {
      return true;
    } else if (createParquetAsIceberg && "parquet".equalsIgnoreCase(provider)) {
      return true;
    } else if (createAvroAsIceberg && "avro".equalsIgnoreCase(provider)) {
      return true;
    } else if (createOrcAsIceberg && "orc".equalsIgnoreCase(provider)) {
      return true;
    }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Configure a delegate that implements TableCatalog, FunctionCatalog, and SupportsNamespaces (e.g. Spark's built-in session catalog)
  2. Check the plugin class's implemented interfaces before assigning it as delegate
  3. Downgrade expectations: use plain SparkCatalog if no valid session delegate is available

Example fix

// before
catalog.setDelegateCatalog(functionOnlyPlugin);
// after
if (plugin instanceof TableCatalog && plugin instanceof FunctionCatalog && plugin instanceof SupportsNamespaces) {
  catalog.setDelegateCatalog(plugin);
}
Defensive patterns

Strategy: type-guard

Validate before calling

// before wiring the delegate
if (!(plugin instanceof TableCatalog) || !(plugin instanceof FunctionCatalog)
    || !(plugin instanceof SupportsNamespaces)) {
  throw new IllegalArgumentException("Delegate must implement TableCatalog, FunctionCatalog, SupportsNamespaces");
}

Type guard

boolean validDelegate(CatalogPlugin p) {
  return p instanceof TableCatalog && p instanceof FunctionCatalog && p instanceof SupportsNamespaces;
}

Try / catch

try {
  sessionCatalog.setDelegateCatalog(plugin);
} catch (IllegalArgumentException e) {
  // use Spark's built-in session catalog as delegate
  sessionCatalog.setDelegateCatalog(spark.sessionState().catalogManager().catalog("spark_catalog").asTableCatalog());
}

Prevention

When it happens

Trigger: Setting spark.sql.catalog.<name> to SparkSessionCatalog and calling setDelegateCatalog with a CatalogPlugin that is not a full table+function+namespace catalog (e.g. a view-only or function-only plugin).

Common situations: Custom or third-party CatalogPlugin implementations lacking SupportsNamespaces; Spark version changes altering the plugin interface; passing the Iceberg catalog itself as its own delegate by mistake.

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