apache/iceberg · error · UnsupportedOperationException
Operation refresh is not supported after the table is serial
Error message
Operation refresh is not supported after the table is serialized
What it means
SerializableTable is an immutable, serialized snapshot of a table. refresh() would reload metadata from the catalog, which is impossible after serialization, so it unconditionally throws UnsupportedOperationException with message 'Operation refresh is not supported after the table is serialized'.
Source
Thrown at core/src/main/java/org/apache/iceberg/SerializableTable.java:307
@Override
public List<PartitionStatisticsFile> partitionStatisticsFiles() {
return lazyTable().partitionStatisticsFiles();
}
@Override
public Map<String, SnapshotRef> refs() {
return refs;
}
@Override
public UUID uuid() {
return uuid;
}
@Override
public void refresh() {
throw new UnsupportedOperationException(errorMsg("refresh"));
}
@Override
public TableScan newScan() {
return lazyTable().newScan();
}
@Override
public IncrementalAppendScan newIncrementalAppendScan() {
return lazyTable().newIncrementalAppendScan();
}
@Override
public IncrementalChangelogScan newIncrementalChangelogScan() {
return lazyTable().newIncrementalChangelogScan();
}
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Re-load the table from the Catalog on the driver and re-serialize/distribute the fresh instance
- Remove refresh() calls when working with the SerializableTable wrapper
- Use the catalog handle (not the serialized table) when refresh semantics are needed
Example fix
// before serializableTable.refresh(); // after table = catalog.loadTable(identifier); // fresh, live table
Defensive patterns
Strategy: try-catch
Validate before calling
if (table instanceof SerializableTable) { /* refresh unsupported; reload from catalog */ } Type guard
boolean supportsRefresh = !(table instanceof SerializableTable);
Try / catch
try { table.refresh(); } catch (UnsupportedOperationException e) { table = catalog.loadTable(identifier); } Prevention
- Treat SerializableTable as immutable; reload from Catalog for fresh metadata
- Keep the Catalog handle available wherever refresh is needed
- Avoid defensive refresh() calls in executor code
When it happens
Trigger: Calling table.refresh() on any SerializableTable instance, typically in task code that received the table via serialization and expects live-catalog semantics.
Common situations: Long-running Spark/Flink jobs re-reading a table expecting fresh metadata; code paths that call refresh() defensively before scanning.
Related errors
- does not have a metadata file location
- Cannot load metadata: metadata file location is null
- does not have a format version
- Operation updateSchema is not supported after the table is s
- Operation updateSpec is not supported after the table is ser
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/7065f67f0a8821d7.
Report an issue: GitHub.