apache/iceberg · error · UnsupportedOperationException
Cannot remove or replace rows in a
Error message
Cannot remove or replace rows in a %s table
What it means
Iceberg throws this UnsupportedOperationException when newRowDelta() is called on a read-only table. RowDelta commits data and delete files (row-level changes), which BaseReadOnlyTable subclasses never allow. The descriptor names the read-only table kind.
Solutions
- Build the RowDelta on the writable data table loaded via catalog.loadTable(identifier).
- Validate the Table reference is a real data table before instantiating writers.
- Use RowDelta only for v2 tables; ensure the target table has format version 2.
Example fix
// before
table.snapshots().newRowDelta().addRows(writer).commit();
// after
Table dataTable = catalog.loadTable(TableIdentifier.of("db", "tbl"));
dataTable.newRowDelta().addRows(writer).commit(); Defensive patterns
Strategy: try-catch
Validate before calling
if (isMetadataTableName(table.name())) { throw new IllegalArgumentException("Cannot apply row deltas to metadata table " + table.name()); } Type guard
boolean canWriteRowDelta = !(table instanceof BaseReadOnlyTable); // ensure handle came from Catalog.loadTable
Try / catch
try {
table.newRowDelta().addRows(writer).commit();
} catch (UnsupportedOperationException e) {
log.error("RowDelta is not supported on read-only table {}", table.name(), e);
} Prevention
- Bind delete/row writers to catalog-loaded data tables only.
- Confirm format version 2 before using RowDelta on the data table.
- Keep metadata-table handles out of writer construction code paths.
When it happens
Trigger: Calling table.newRowDelta().addRows(...).addDeletes(...).commit() on a metadata table or any BaseReadOnlyTable subclass instance.
Common situations: Row-level delete writers (e.g. CDC or merge-on-read writers) that were given a metadata-table handle instead of the data table.
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 append to a table
- Cannot create transactions for a
- Cannot delete from a
- Cannot expire snapshots from a
- Cannot manage snapshots in a
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/1d5d6a45ef77893d.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/BaseReadOnlyTable.java:82
@Override
public RewriteFiles newRewrite() {
throw new UnsupportedOperationException("Cannot rewrite in a " + descriptor + " table");
}
@Override
public RewriteManifests rewriteManifests() {
throw new UnsupportedOperationException(
"Cannot rewrite manifests in a " + descriptor + " table");
}
@Override
public OverwriteFiles newOverwrite() {
throw new UnsupportedOperationException("Cannot overwrite in a " + descriptor + " table");
}
@Override
public RowDelta newRowDelta() {
throw new UnsupportedOperationException(
"Cannot remove or replace rows in a " + descriptor + " table");
}
@Override
public ReplacePartitions newReplacePartitions() {
throw new UnsupportedOperationException(
"Cannot replace partitions in a " + descriptor + " table");
}
@Override
public DeleteFiles newDelete() {
throw new UnsupportedOperationException("Cannot delete from a " + descriptor + " table");
}
@Override
public UpdateStatistics updateStatistics() {
throw new UnsupportedOperationException(
"Cannot update statistics of a " + descriptor + " table");View on GitHub (pinned to 86d9c8fc54)