apache/iceberg · error · UnsupportedOperationException
Not a supported type: ${targetType}
Error message
Not a supported type: ${targetType} What it means
DataConverter.get() builds a converter for pairs of Flink logical types but only supports RowType, ArrayType, and MapType at the top level. Any other LogicalType (e.g. raw VARBINARY used here, or unsupported roots) hits the default branch and raises UnsupportedOperationException.
Source
Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/sink/dynamic/DataConverter.java:127
};
case TIMESTAMP_WITHOUT_TIME_ZONE:
return object -> {
if (object instanceof Integer) {
LocalDateTime dateTime =
LocalDateTime.of(LocalDate.ofEpochDay((Integer) object), LocalTime.MIN);
return TimestampData.fromLocalDateTime(dateTime);
} else {
return object;
}
};
case ROW:
return new RowDataConverter((RowType) sourceType, (RowType) targetType);
case ARRAY:
return new ArrayConverter((ArrayType) sourceType, (ArrayType) targetType);
case MAP:
return new MapConverter((MapType) sourceType, (MapType) targetType);
default:
throw new UnsupportedOperationException("Not a supported type: " + targetType);
}
}
static DataConverter nullable(DataConverter converter) {
return value -> value == null ? null : converter.convert(value);
}
class RowDataConverter implements DataConverter {
private final RowData.FieldGetter[] fieldGetters;
private final DataConverter[] dataConverters;
RowDataConverter(RowType sourceType, RowType targetType) {
this.fieldGetters = new RowData.FieldGetter[targetType.getFields().size()];
this.dataConverters = new DataConverter[targetType.getFields().size()];
for (int i = 0; i < targetType.getFields().size(); i++) {
RowData.FieldGetter fieldGetter;
DataConverter dataConverter;View on GitHub (pinned to 86d9c8fc54)
Solutions
- Ensure the evolving field types are restricted to ROW, ARRAY, or MAP structures supported by the dynamic sink.
- If a type was evolved to an unsupported one, roll back the schema change or add an explicit case to DataConverter.get for that type.
- Pre-transform data so the target field uses a supported type before writing.
Example fix
// before: target field type = VARBINARY // after: keep the field as BINARY<->BYTES compatible or wrap in a supported structure ALTER TABLE db.t MODIFY COLUMN payload BYTES; // if BYTES<->VARBINARY handled upstream, else avoid this evolution
Defensive patterns
Strategy: validation
Validate before calling
LogicalType root = targetType;
if (!(root instanceof RowType || root instanceof ArrayType || root instanceof MapType)) {
throw new IllegalArgumentException("Dynamic sink only supports ROW/ARRAY/MAP roots, got: " + root);
} Type guard
static boolean isSupportedRoot(LogicalType t) {
return t instanceof RowType || t instanceof ArrayType || t instanceof MapType;
} Prevention
- Restrict schema evolution to supported type categories (row/array/map).
- Test schema changes on a staging table before applying to production.
When it happens
Trigger: Calling the dynamic sink's DataConverter.get(sourceType, targetType) where targetType's root logical type is not ROW, ARRAY, or MAP — e.g. a top-level column type of BINARY/VARBINARY or a custom logical type.
Common situations: Schema evolution where a field's type changed into an unsupported category; users feeding non-row-rooted types into the dynamic sink's schema-compatibility machinery.
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
- Unsupported Avro type '${schema.getType()}'.
- Unsupported element type: ${elementType}
- Unsupported Avro type '${schema.getType()}'.
- Unsupported Avro type '" + schema.getType() + "'.
- Field %d has unsupported field type: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/f834aba2a7c05968.
Report an issue: GitHub.