apache/iceberg · error · UnsupportedOperationException

Remove is not supported

Error message

Remove is not supported

What it means

DVIterator.remove implements the JDK Iterator contract but throws UnsupportedOperationException because the iterator is read-only. Deletion-vector iterators must never mutate the underlying data stream. Calling remove() is always a caller bug.

Source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/DVIterator.java:104

          rowValues.add(ScanTaskUtil.contentSizeInBytes(deleteFile));
        } else if (fieldId == MetadataColumns.DELETE_FILE_ROW_FIELD_ID) {
          // DVs don't track the row that was deleted
          rowValues.add(null);
        }
      }

      this.row = new GenericInternalRow(rowValues.toArray());
    } else if (null != deletedPositionIndex) {
      // only update the deleted position if necessary, everything else stays the same
      row.update(deletedPositionIndex, position);
    }

    return row;
  }

  @Override
  public void remove() {
    throw new UnsupportedOperationException("Remove is not supported");
  }

  @Override
  public void close() {}
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Do not call remove(); iterate read-only and collect rows to keep into a new collection instead.
  2. If deletion is intended, write a delete file / deletion vector via the Iceberg writer API instead of mutating scan output.

Example fix

// before
while (it.hasNext()) { Row r = it.next(); if (bad(r)) it.remove(); }
// after
List<Row> kept = new ArrayList<>();
while (it.hasNext()) { Row r = it.next(); if (!bad(r)) kept.add(r); }
Defensive patterns

Strategy: fallback

Try / catch

// do not call remove(); implement filtering instead
// pattern: if (iter instanceof DVMutabilityCheck d && !d.isMutable()) collectInstead();

Prevention

When it happens

Trigger: Any code invoking iterator.remove() on the InternalRow iterator produced for a deletion-vector scan task — typically generic collection-consuming frameworks that call remove() to prune elements.

Common situations: Custom Spark readers/extensions iterating DV results with mutable Iterator usage; third-party code assuming all Iceberg iterators are mutable.

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/1877363ec017c259. Report an issue: GitHub.