apache/iceberg · error · UnsupportedOperationException

Cannot call refresh on temporary table operations

Error message

Cannot call refresh on temporary table operations

What it means

During commit, HadoopTableOperations builds a temporary TableOperations wrapper holding uncommitted metadata to compute the new state. Its refresh() is intentionally unsupported because there is no on-disk state to refresh from; calling it throws UnsupportedOperationException. It is an internal API-misuse guard, not a runtime condition.

Source

Thrown at core/src/main/java/org/apache/iceberg/hadoop/HadoopTableOperations.java:199

    return LocationProviders.locationsFor(current().location(), current().properties());
  }

  @Override
  public String metadataFileLocation(String fileName) {
    return metadataPath(fileName).toString();
  }

  @Override
  public TableOperations temp(TableMetadata uncommittedMetadata) {
    return new TableOperations() {
      @Override
      public TableMetadata current() {
        return uncommittedMetadata;
      }

      @Override
      public TableMetadata refresh() {
        throw new UnsupportedOperationException(
            "Cannot call refresh on temporary table operations");
      }

      @Override
      public void commit(TableMetadata base, TableMetadata metadata) {
        throw new UnsupportedOperationException("Cannot call commit on temporary table operations");
      }

      @Override
      public String metadataFileLocation(String fileName) {
        return HadoopTableOperations.this.metadataFileLocation(fileName);
      }

      @Override
      public LocationProvider locationProvider() {
        return LocationProviders.locationsFor(
            uncommittedMetadata.location(), uncommittedMetadata.properties());
      }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Do not call refresh() on operations instances obtained during a commit; only refresh the outer HadoopTableOperations
  2. Capture needed state (e.g., uncommittedMetadata via current()) instead of refreshing
  3. Restructure code so refresh happens before commit() begins, not inside it

Example fix

// before: inside a commit-time callback
tempOps.refresh();
// after
TableMetadata pending = tempOps.current(); // use in-memory state instead
Defensive patterns

Strategy: type-guard

Validate before calling

if (isTemporaryOps(ops)) { /* skip refresh */ }

Type guard

boolean isRefreshable(TableOperations ops) { return ops instanceof HadoopTableOperations; }

Prevention

When it happens

Trigger: Calling refresh() on the temporary operations instance exposed during a commit transaction; code that generically calls ops.refresh() on any TableOperations it holds, including the transient one from within a commit callback.

Common situations: Custom commit listeners or hooks that refresh the table mid-commit; reflection-driven or generic framework code treating all TableOperations uniformly.

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