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
- Do not call refresh() on operations instances obtained during a commit; only refresh the outer HadoopTableOperations
- Capture needed state (e.g., uncommittedMetadata via current()) instead of refreshing
- 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
- Never call refresh() inside commit-time hooks or on transient operations instances
- Read in-memory state via current() on temporary operations
- Centralize refresh logic to operate only on the outer operations object
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
- Cannot call commit on temporary table operations
- Cannot call commit on temporary table operations
- Update type %s is not supported
- Cannot call commit on temporary table operations
- Cannot call commit on temporary table operations
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/e5d612e7d70b19b8.
Report an issue: GitHub.