apache/iceberg · error · UnsupportedOperationException

Cannot retrieve UUID for table

Error message

Cannot retrieve UUID for table 

What it means

Spark3Util.uuid() cannot determine a table's UUID because the given Table object does not expose TableOperations. Only tables backed by real Iceberg metadata (HasTableOperations) or metadata tables (BaseMetadataTable) have a UUID; other wrappers (e.g. Spark cached/wrapped tables or foreign catalog tables) do not.

Solutions

  1. Unwrap the table before calling uuid(): pass ((BaseTable) table).table() if the wrapper exposes the underlying table
  2. If you own the Table implementation, implement HasTableOperations so the operations (and metadata UUID) are reachable
  3. Verify the table was loaded through the Iceberg catalog, not a third-party catalog that returns non-Iceberg Table objects

Example fix

// before
String uuid = Spark3Util.uuid(wrappedTable);
// after
Table base = (wrappedTable instanceof BaseTable) ? ((BaseTable) wrappedTable).table() : wrappedTable;
String uuid = Spark3Util.uuid(base);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(table instanceof BaseTable) && !(table instanceof HasTableOperations) && !(table instanceof BaseMetadataTable)) {
  throw new IllegalArgumentException("Table " + table.name() + " has no Iceberg operations; UUID unavailable");
}

Type guard

boolean hasUuid(Table t) { return t instanceof HasTableOperations || t instanceof BaseMetadataTable; }

Try / catch

try { uuid = Spark3Util.uuid(table); } catch (UnsupportedOperationException e) { /* fall back to table.toString() or skip */ }

Prevention

When it happens

Trigger: Calling Spark3Util.uuid(table) with a Table instance that is neither a HasTableOperations nor a BaseMetadataTable, e.g. a table wrapped by SparkCachedTableCatalog's cached Table or a custom Catalog implementation's Table.

Common situations: Running DESCRIBE TABLE EXTENDED or metadata queries through a Spark session whose catalog resolves tables to wrapped/proxied Table objects rather than the underlying BaseTable; custom catalog integrations returning non-standard Table implementations.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:995

    Preconditions.checkArgument(
        namespace.length <= 1,
        "Cannot convert %s to a Spark v1 identifier, namespace contains more than 1 part",
        identifier);

    String table = identifier.name();
    Option<String> database = namespace.length == 1 ? Option.apply(namespace[0]) : Option.empty();
    return org.apache.spark.sql.catalyst.TableIdentifier.apply(table, database);
  }

  static String baseTableUUID(org.apache.iceberg.Table table) {
    if (table instanceof HasTableOperations) {
      TableOperations ops = ((HasTableOperations) table).operations();
      return ops.current().uuid();
    } else if (table instanceof BaseMetadataTable) {
      return ((BaseMetadataTable) table).table().operations().current().uuid();
    } else {
      throw new UnsupportedOperationException("Cannot retrieve UUID for table " + table.name());
    }
  }

  private static class DescribeSortOrderVisitor implements SortOrderVisitor<String> {
    private static final DescribeSortOrderVisitor INSTANCE = new DescribeSortOrderVisitor();

    private DescribeSortOrderVisitor() {}

    @Override
    public String field(
        String sourceName,
        int sourceId,
        org.apache.iceberg.SortDirection direction,
        NullOrder nullOrder) {
      return String.format("%s %s %s", sourceName, direction, nullOrder);
    }

    @Override

View on GitHub (pinned to 86d9c8fc54)