apache/iceberg · error · java.lang.UnsupportedOperationException
Not supported yet.
Error message
Not supported yet.
What it means
StructRowData.getRawValue(pos) is part of Flink's RowData contract for RawValueData access, but Iceberg's implementation does not support raw value access and throws UnsupportedOperationException unconditionally. Raw value semantics (pass-through binary) are not applicable to projected Iceberg struct rows.
Source
Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/data/StructRowData.java:215
LocalDateTime ldt = (LocalDateTime) timeVal;
return TimestampData.fromEpochMillis(
ldt.toInstant(ZoneOffset.UTC).toEpochMilli(), ldt.getNano() % 1_000_000);
} else if (timeVal instanceof Long) {
long timeLong = (Long) timeVal;
return TimestampData.fromEpochMillis(
Math.floorDiv(timeLong, 1_000_000L), (int) Math.floorMod(timeLong, 1_000_000L));
} else {
throw new IllegalStateException("Unknown type for timestamp_ns: " + timeVal.getClass());
}
}
long timeLong = getLong(pos);
return TimestampData.fromEpochMillis(
Math.floorDiv(timeLong, 1000L), (int) Math.floorMod(timeLong, 1000L) * 1000);
}
@Override
public <T> RawValueData<T> getRawValue(int pos) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public byte[] getBinary(int pos) {
return isNullAt(pos) ? null : getBinaryInternal(pos);
}
private byte[] getBinaryInternal(int pos) {
Object bytes = struct.get(pos, Object.class);
// should only be either ByteBuffer or byte[]
if (bytes instanceof ByteBuffer) {
return ByteBuffers.toByteArray((ByteBuffer) bytes);
} else if (bytes instanceof byte[]) {
return (byte[]) bytes;
} else if (bytes instanceof UUID) {
UUID uuid = (UUID) bytes;
ByteBuffer bb = ByteBuffer.allocate(16);View on GitHub (pinned to 86d9c8fc54)
Solutions
- Materialize the field via typed accessors (getInt/getLong/getString/getBinary) and construct RawValueData yourself if needed
- Ensure downstream operators don't call getRawValue on Iceberg-projected rows (e.g. wrap rows in GenericRowData)
- Reorder the pipeline so RawValueData usage happens before Iceberg projection wrapping
Example fix
// before RawValueData<String> raw = structRowData.getRawValue(pos); // throws // after String s = structRowData.getString(pos); RawValueData<String> raw = StringData.fromString(s);
Defensive patterns
Strategy: try-catch
Try / catch
try { RawValueData<T> raw = row.getRawValue(pos); } catch (UnsupportedOperationException e) { T value = typedAccessor(row, pos); raw = RawValueData.fromObject(value); } Prevention
- Never rely on getRawValue for Iceberg StructRowData
- Use typed accessors to build RawValueData when needed
- Wrap projected rows before passing to raw-value-aware operators
When it happens
Trigger: Calling getRawValue(...) on a StructRowData, e.g. from a Flink sink or operator that uses RawValueData APIs (such as some serialization paths or async sinks).
Common situations: Connecting Iceberg scan output directly to operators that call getRawValue on all RowData; generic RowData-processing utilities that touch every accessor.
Related errors
- Could not set a field in the RowDataWrapper because rowData
- Cannot set row kind in the RowDataProjection
- 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/00bfce630bc90f5d.
Report an issue: GitHub.