apache/iceberg · error · UnsupportedOperationException
Cannot apply update to a table
Error message
Cannot apply update %s to a table
What it means
UnsupportedOperationException thrown by the default MetadataUpdate.applyTo methods when an update implementation does not support applying to table (or view) metadata. Each MetadataUpdate subclass overrides the applyTo relevant to its target; calling the other variant — or a custom update that overrides neither — reaches the default throw. It signals applying an update to the wrong metadata type.
Solutions
- Apply table-targeted updates only to TableMetadata.Builder and view-targeted updates only to ViewMetadata.Builder; filter the update list by update class.
- If implementing a new MetadataUpdate, override the appropriate applyTo method.
- Check update compatibility before applying (e.g., instanceof ViewUpdate vs table update).
- If replaying REST metadata changes, split updates into table and view lists by class before applying.
Example fix
// before
for (MetadataUpdate update : updates) {
update.applyTo(tableBuilder); // throws for view-only updates
}
// after
for (MetadataUpdate update : updates) {
if (!(update instanceof ViewUpdate)) {
update.applyTo(tableBuilder);
}
} Defensive patterns
Strategy: type-guard
Validate before calling
// split updates by target before applying List<MetadataUpdate> tableUpdates = updates.stream().filter(u -> !(u instanceof ViewUpdate)).toList();
Type guard
boolean isTableUpdate(MetadataUpdate u) { return !(u instanceof ViewUpdate); } Try / catch
try {
update.applyTo(tableBuilder);
} catch (UnsupportedOperationException e) {
// update targets views; apply to ViewMetadata.Builder instead
} Prevention
- Only apply table updates to TableMetadata.Builder and view updates to ViewMetadata.Builder
- Override the correct applyTo when implementing new MetadataUpdate types
- Filter mixed update lists by class before replaying
When it happens
Trigger: Calling MetadataUpdate.applyTo(TableMetadata.Builder) with an update class that only supports views (e.g., AssignUUID for views path, or view-specific updates) or a custom/unknown implementation that overrides neither method.
Common situations: Custom catalog code replaying a mixed list of table and view updates against one builder; REST metadata processing where update objects are applied to the wrong builder; adding a new MetadataUpdate subclass without overriding applyTo.
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 apply update to a view
- Altering a view is not supported by catalog:
- Altering a view is not supported by catalog
- Altering a view is not supported by catalog
- Altering a view is not supported by catalog
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/fa4ca39a5c47c910.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/MetadataUpdate.java:33
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.iceberg;
import java.io.Serializable;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.iceberg.encryption.EncryptedKey;
import org.apache.iceberg.relocated.com.google.common.collect.ImmutableSet;
import org.apache.iceberg.view.ViewMetadata;
import org.apache.iceberg.view.ViewVersion;
/** Represents a change to table or view metadata. */
public interface MetadataUpdate extends Serializable {
default void applyTo(TableMetadata.Builder metadataBuilder) {
throw new UnsupportedOperationException(
String.format("Cannot apply update %s to a table", this.getClass().getSimpleName()));
}
default void applyTo(ViewMetadata.Builder viewMetadataBuilder) {
throw new UnsupportedOperationException(
String.format("Cannot apply update %s to a view", this.getClass().getSimpleName()));
}
class AssignUUID implements MetadataUpdate {
private final String uuid;
public AssignUUID(String uuid) {
this.uuid = uuid;
}
public String uuid() {
return uuid;
}View on GitHub (pinned to 86d9c8fc54)