apache/iceberg · error · UnsupportedOperationException

this.getClass().getName() + " does not implement insert"

Error message

this.getClass().getName() + " does not implement insert"

What it means

The position-delete-based writer in SparkPositionDeltaWrite does not implement insert(). In this writer variant rows are only written as position deletes against existing files, so inserting new data rows is not supported; the class name in the message identifies the offending writer.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/SparkPositionDeltaWrite.java:653

      InternalRow partition = metadata.getStruct(partitionOrdinal, partitionRowWrapper.size());
      StructProjection partitionProjection = partitionProjections.get(specId);
      partitionProjection.wrap(partitionRowWrapper.wrap(partition));

      String file = id.getString(fileOrdinal);
      long position = id.getLong(positionOrdinal);
      positionDelete.set(file, position);
      delegate.write(positionDelete, spec, partitionProjection);
    }

    @Override
    public void update(InternalRow metadata, InternalRow id, InternalRow row) {
      throw new UnsupportedOperationException(
          this.getClass().getName() + " does not implement update");
    }

    @Override
    public void insert(InternalRow row) throws IOException {
      throw new UnsupportedOperationException(
          this.getClass().getName() + " does not implement insert");
    }

    @Override
    public WriterCommitMessage commit() throws IOException {
      close();

      DeleteWriteResult result = delegate.result();
      return new DeltaTaskCommit(result);
    }

    @Override
    public void abort() throws IOException {
      close();

      DeleteWriteResult result = delegate.result();
      SparkCleanupUtil.deleteTaskFiles(io, result.deleteFiles());
    }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use the copy-on-write/merge-on-read writer variants (which implement insert via reinsert) for rows that must be written.
  2. Restrict this writer to delete-only operations; route inserts to the corresponding data writer.
  3. Check that the row-level operation mode matches the intended write type before execution.
  4. Upgrade Iceberg if this occurs in an unmodified engine integration.
Defensive patterns

Strategy: validation

Validate before calling

if (writer instanceof SparkPositionDeltaWrite.PositionDeltaWriter) { /* inserts unsupported here */ }

Try / catch

try { writer.insert(row); } catch (UnsupportedOperationException e) { routeInsertToDataWriter(row); }

Prevention

When it happens

Trigger: DeltaWriter.insert(InternalRow row) is invoked on the position-delete writer of SparkPositionDeltaWrite, i.e. when the framework asks a delete-only writer to add new rows.

Common situations: Custom DeltaWriter usage mixing insert semantics with a position-delete writer; engine code routing copied/updated rows to the wrong writer during MERGE/UPDATE execution.

Related errors


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