apache/iceberg · error · UnsupportedOperationException

Cannot manage snapshots in a

Error message

Cannot manage snapshots in a %s table

What it means

ManageSnapshots performs metadata mutations (rollback, cherry-pick, branch/tag management) which require a writable table. BaseReadOnlyTable.manageSnapshots() always throws UnsupportedOperationException.

Solutions

  1. Load the real table via catalog.loadTable() and call manageSnapshots() on it.
  2. Use rollback on the writable table: table.manageSnapshots().rollbackTo(snapshotId).commit().
  3. Ensure time-travel reads use the read-only handle only for scanning.

Example fix

// before
readOnlyTable.manageSnapshots().rollbackTo(snapshotId).commit();
// after
Table table = catalog.loadTable(tableIdentifier);
table.manageSnapshots().rollbackTo(snapshotId).commit();
Defensive patterns

Strategy: validation

Validate before calling

if (!(table instanceof BaseReadOnlyTable)) {
  table.manageSnapshots().rollbackTo(snapshotId).commit();
}

Type guard

boolean supportsSnapshotManagement(Table t) { return !(t instanceof BaseReadOnlyTable); }

Try / catch

try { table.manageSnapshots().rollbackTo(id).commit(); } catch (UnsupportedOperationException e) { /* reload from catalog */ }

Prevention

When it happens

Trigger: Calling table.manageSnapshots() on a read-only descriptor such as a snapshot wrapper obtained from a table's snapshot APIs.

Common situations: Rollback tooling that grabbed a snapshot handle and tried to roll the table back to it directly.

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

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/BaseReadOnlyTable.java:117

    throw new UnsupportedOperationException(
        "Cannot update statistics of a " + descriptor + " table");
  }

  @Override
  public UpdatePartitionStatistics updatePartitionStatistics() {
    throw new UnsupportedOperationException(
        "Cannot update partition statistics of a " + descriptor + " table");
  }

  @Override
  public ExpireSnapshots expireSnapshots() {
    throw new UnsupportedOperationException(
        "Cannot expire snapshots from a " + descriptor + " table");
  }

  @Override
  public ManageSnapshots manageSnapshots() {
    throw new UnsupportedOperationException(
        "Cannot manage snapshots in a " + descriptor + " table");
  }

  @Override
  public Transaction newTransaction() {
    throw new UnsupportedOperationException(
        "Cannot create transactions for a " + descriptor + " table");
  }
}

View on GitHub (pinned to 86d9c8fc54)