apache/iceberg · error · UnsupportedOperationException

Updating statistics is not supported by + getClass().getName

Error message

Updating statistics is not supported by + getClass().getName()

What it means

The default Transaction.updateStatistics() throws UnsupportedOperationException because transactions created by some implementations cannot stage table-statistics file changes. Only transaction implementations tied to tables supporting statistics updates override this method; the message names the concrete Transaction class lacking support.

Source

Thrown at api/src/main/java/org/apache/iceberg/Transaction.java:147

   * @return a new {@link ReplacePartitions}
   */
  ReplacePartitions newReplacePartitions();

  /**
   * Create a new {@link DeleteFiles delete API} to delete files in this table.
   *
   * @return a new {@link DeleteFiles}
   */
  DeleteFiles newDelete();

  /**
   * Create a new {@link UpdateStatistics update table statistics API} to add or remove statistics
   * files in this table.
   *
   * @return a new {@link UpdateStatistics}
   */
  default UpdateStatistics updateStatistics() {
    throw new UnsupportedOperationException(
        "Updating statistics is not supported by " + getClass().getName());
  }

  /**
   * Create a new {@link UpdatePartitionStatistics update partition statistics API} to add or remove
   * partition statistics files in this table.
   *
   * @return a new {@link UpdatePartitionStatistics}
   */
  default UpdatePartitionStatistics updatePartitionStatistics() {
    throw new UnsupportedOperationException(
        "Updating partition statistics is not supported by " + getClass().getName());
  }

  /**
   * Create a new {@link ExpireSnapshots expire API} to expire snapshots in this table.
   *
   * @return a new {@link ExpireSnapshots}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Apply the statistics update directly on the table (table.updateStatistics()...commit()) rather than inside the transaction.
  2. Use the table's underlying transaction (BaseTable's transaction) which supports updateStatistics.
  3. Catch UnsupportedOperationException and perform the statistics update as a separate commit.
  4. Override updateStatistics() in custom Transaction implementations.

Example fix

// before
Transaction txn = table.newTransaction();
txn.updateStatistics().addStatisticsFile(stats).commit();
txn.commitTransaction();

// after
table.updateStatistics().addStatisticsFile(stats).commit(); // direct, supported path
Defensive patterns

Strategy: fallback

Validate before calling

// probe transaction support before staging statistics
try {
  txn.updateStatistics();
} catch (UnsupportedOperationException e) {
  useDirectTableUpdate(table);
}

Type guard

boolean txnSupportsStats(Transaction txn) {
  try { txn.updateStatistics(); return true; }
  catch (UnsupportedOperationException e) { return false; }
}

Try / catch

try {
  txn.updateStatistics().addStatisticsFile(f).commit();
} catch (UnsupportedOperationException e) {
  table.updateStatistics().addStatisticsFile(f).commit(); // standalone commit
}

Prevention

When it happens

Trigger: Calling transaction.updateStatistics() (e.g. in testEmptyTransactionalUpdateStatistics or orphan-file cleanup paths that remove statistics files transactionally) on a Transaction implementation that does not override it — commonly transactions created outside a full BaseTransaction context.

Common situations: Wrapping statistics updates inside a multi-operation transaction for atomicity; running ExpireSnapshots/statistics cleanup through a transaction on tables or wrappers that don't support transactional statistics updates.

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