apache/iceberg · error · java.lang.UnsupportedOperationException
Could not set a field in the RowDataWrapper because rowData
Error message
Could not set a field in the RowDataWrapper because rowData is read-only
What it means
RowDataWrapper wraps a Flink RowData as an Iceberg StructLike, which is a read-only view: it only supports reading fields via positional getters backed by the underlying RowData. The set(int, T) method is therefore unsupported by design and always throws this UnsupportedOperationException whenever any code attempts to mutate a position through the wrapper. It fires when a component treats the StructLike as writable (e.g., an accumulator or reusable struct in an aggregation path tries to write into it); the offending input is the mutation attempt on the wrapped read-only rowData.
Source
Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/RowDataWrapper.java:83
}
@Override
public int size() {
return types.length;
}
@Override
public <T> T get(int pos, Class<T> javaClass) {
if (rowData.isNullAt(pos)) {
return null;
}
return javaClass.cast(getters[pos].get(rowData, pos));
}
@Override
public <T> void set(int pos, T value) {
throw new UnsupportedOperationException(
"Could not set a field in the RowDataWrapper because rowData is read-only");
}
private interface PositionalGetter<T> {
T get(RowData data, int pos);
}
private static PositionalGetter<?> buildGetter(LogicalType logicalType, Type type) {
switch (logicalType.getTypeRoot()) {
case TINYINT:
return (row, pos) -> (int) row.getByte(pos);
case SMALLINT:
return (row, pos) -> (int) row.getShort(pos);
case CHAR:
case VARCHAR:
return (row, pos) -> row.getString(pos).toString();
case BINARY:View on GitHub (pinned to 86d9c8fc54)
Solutions
- Do not call set() on RowDataWrapper; build a mutable StructLike (e.g. a new row / GenericRowData) instead.
- Wrap the target in a dedicated writable StructLike implementation for the write path.
Example fix
// before wrapper.set(0, 42L); // throws // after GenericRowData row = new GenericRowData(arity); row.setField(0, 42L);
Defensive patterns
Strategy: type-guard
Validate before calling
// only use wrapper for read paths Objects.requireNonNull(wrapper, "wrapper");
Type guard
if (structLike instanceof RowDataWrapper) { throw new IllegalStateException("RowDataWrapper is read-only; use a mutable StructLike for writes"); } Try / catch
try { wrapper.set(pos, v); } catch (UnsupportedOperationException e) { /* fall back to mutable row */ } Prevention
- Treat RowDataWrapper as read-only StructLike.
- Use GenericRowData or a custom writable wrapper for mutation paths.
- Review StructLike usage in generic utility code.
When it happens
Trigger: Any code path that treats the wrapper as a writable StructLike and calls set(pos, value) — e.g. generic metadata-writing or update code handed this wrapper as a StructLike row.
Common situations: Reusing a StructLike wrapper designed for reading scan output in a write path; framework code that assumes StructLike implementations 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
- Cannot set fields in a TypeProjection
- Cannot update InternalRecordWrapper
- Altering schema is not supported in the old alterTable API.
- Altering partition keys is not supported yet.
- Creating table with computed columns is not supported yet.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/bb55f55c0601217d.
Report an issue: GitHub.