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);
}
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Set the row kind on the underlying RowData before wrapping it in RowDataProjection.
- Copy the projected fields into a new MutableRowData/GenericRowData and set the kind on the copy.
- Restructure the pipeline so kind mutation happens before projection.
- 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
- Treat RowDataProjection as immutable; set kinds on the source RowData
- Copy projected fields into GenericRowData if downstream needs mutable rows
- Reorder pipelines: mutate kind before projecting
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
- Could not set a field in the RowDataWrapper because rowData
- Not supported yet.
- Not supported yet.
- Altering schema is not supported in the old alterTable API.
- Altering partition keys is not supported yet.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/afc02404338a1e00.
Report an issue: GitHub.