apache/iceberg · error · UnsupportedOperationException

Cannot set row kind in the RowDataProjection

Error message

Cannot set row kind in the RowDataProjection

What it means

RowDataProjection wraps an inner RowData to project a subset of fields. Row kind is not part of the projected value, so setRowKind is intentionally unsupported and always throws UnsupportedOperationException. This is a deliberate API contract, not a failure condition.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/data/RowDataProjection.java:197

  private Object getValue(int pos) {
    Preconditions.checkState(rowData != null, "Row data not wrapped");
    return getters[pos].getFieldOrNull(rowData);
  }

  @Override
  public int getArity() {
    return getters.length;
  }

  @Override
  public RowKind getRowKind() {
    Preconditions.checkState(rowData != null, "Row data not wrapped");
    return rowData.getRowKind();
  }

  @Override
  public void setRowKind(RowKind kind) {
    throw new UnsupportedOperationException("Cannot set row kind in the RowDataProjection");
  }

  @Override
  public boolean isNullAt(int pos) {
    return getValue(pos) == null;
  }

  @Override
  public boolean getBoolean(int pos) {
    return (boolean) getValue(pos);
  }

  @Override
  public byte getByte(int pos) {
    return (byte) getValue(pos);
  }

  @Override

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Set the row kind on the underlying RowData before wrapping it in RowDataProjection.
  2. Copy the projected fields into a new MutableRowData/GenericRowData and set the kind on the copy.
  3. Restructure the pipeline so kind mutation happens before projection.
  4. If kind must flow through projection, use the original RowData rather than the projection at that operator.

Example fix

// before
RowDataProjection proj = RowDataProjection.of(...);
proj.setRowKind(RowKind.DELETE); // throws
// after
wrapped.setRowKind(RowKind.DELETE);
RowDataProjection proj = RowDataProjection.of(rowType, positions, types);
Defensive patterns

Strategy: fallback

Try / catch

try {
  row.setRowKind(kind);
} catch (UnsupportedOperationException e) {
  // set kind on the wrapped/underlying RowData instead
  underlyingRow.setRowKind(kind);
}

Prevention

When it happens

Trigger: Calling setRowKind(...) on a RowDataProjection instance, typically when passing the projected RowData to Flink APIs (e.g. sink runtime code or a DataStream map) that mutates row kinds in place.

Common situations: Flink changelog pipelines (CDC) where operators like DataStreamScan or custom sinks call setRowKind on projected rows; wrapping projected rows into operators that assume mutable RowData.

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/afc02404338a1e00. Report an issue: GitHub.