apache/iceberg · error · UnsupportedOperationException
Cannot delete from a
Error message
Cannot delete from a %s table
What it means
BaseReadOnlyTable disables all row mutation, including deletes. newDelete() unconditionally throws UnsupportedOperationException because a read-only table descriptor has no commit path to rewrite or delete data files.
Solutions
- Load a writable table via catalog.loadTable(identifier) before invoking newDelete().
- Check the table handle type/capability before issuing deletes.
- Perform deletes on the real table and use snapshot references only for reads.
Example fix
// before readOnlyTable.newDelete().deleteFromRowFilter(expr).commit(); // after Table table = catalog.loadTable(tableIdentifier); table.newDelete().deleteFromRowFilter(expr).commit();
Defensive patterns
Strategy: validation
Validate before calling
if (!(table instanceof BaseReadOnlyTable)) {
table.newDelete().deleteFromRowFilter(expr).commit();
} Type guard
boolean isWritable(Table t) { return !(t instanceof BaseReadOnlyTable); } Try / catch
try { table.newDelete()...commit(); } catch (UnsupportedOperationException e) { throw new IllegalStateException("Cannot delete via read-only handle", e); } Prevention
- Feature-check the table handle before generic delete routines
- Keep maintenance code bound to catalog-loaded tables
- Document in shared libraries that snapshot handles are read-only
When it happens
Trigger: Calling table.newDelete() (DeleteFiles API) on a read-only table instance such as a snapshot wrapper or metadata-backed table.
Common situations: Generic maintenance code (row-level deletes, GDPR-style deletes) applied to a table handle obtained from a snapshot or metadata table; copy-on-write engines acquiring a table handle through read-only APIs.
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 expire snapshots from a
- Cannot manage snapshots in a
- Cannot overwrite in a
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/533f260f2efeb239.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/BaseReadOnlyTable.java:94
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");
}
@Override
public UpdatePartitionStatistics updatePartitionStatistics() {
throw new UnsupportedOperationException(
"Cannot update partition statistics of a " + descriptor + " table");
}
@Override
public ExpireSnapshots expireSnapshots() {
throw new UnsupportedOperationException(
"Cannot expire snapshots from a " + descriptor + " table");View on GitHub (pinned to 86d9c8fc54)