apache/seatunnel · error · org.apache.seatunnel.common.exception.SeaTunnelRuntimeException
COMMON-17
COMMON-17
Error message
'<identifier>' unsupported convert type '<dataType>' of '<field>' to SeaTunnel data type.
What it means
IcebergTypeMapper.mapping converts an Iceberg Type to a SeaTunnel type. If the Iceberg type is not one of the handled kinds (primitives, STRUCT, LIST, MAP — e.g. certain nested or logical types), the default branch throws COMMON-17 convertToSeaTunnelTypeError with 'Iceberg', the type's toString, and the field name.
Solutions
- Identify the unsupported Iceberg type from the error message (dataType field)
- Change the column type in the Iceberg table (e.g. cast fixed/uuid to binary/string where supported)
- Upgrade SeaTunnel to a version whose IcebergTypeMapper supports the type
- Add a mapping case for the type in a custom build of IcebergTypeMapper
Example fix
// before Types.UUIDType.get() // after Types.StringType.get()
Defensive patterns
Strategy: validation
Validate before calling
// Validate Iceberg types before mapping
org.apache.iceberg.types.TypeUtil.visit(icebergSchema.asStruct(),
new org.apache.iceberg.types.TypeUtil.CustomOrderTypeVisitor<Object>(null) {
@Override public Object primitive(org.apache.iceberg.types.Types.PrimitiveType p) {
if (p.typeId() == org.apache.iceberg.types.Type.TypeID.UUID
|| p.typeId() == org.apache.iceberg.types.Type.TypeID.FIXED) {
throw new IllegalArgumentException("Unsupported Iceberg type: " + p);
}
return null;
}
}); Type guard
boolean isSupportedIcebergType(org.apache.iceberg.types.Type t) {
switch (t.typeId()) {
case BOOLEAN: case INTEGER: case LONG: case FLOAT:
case DOUBLE: case STRING: case DATE: case TIMESTAMP:
case DECIMAL: case BINARY: case STRUCT: case LIST: case MAP:
return true;
default:
return false; // e.g. UUID, FIXED
}
} Prevention
- Avoid UUID and fixed(n) columns in Iceberg tables read by SeaTunnel
- Cast unsupported nested leaf types to supported ones in table DDL
- Keep the Iceberg writer and SeaTunnel connector versions aligned
- Walk the full nested schema with TypeUtil before ingestion
When it happens
Trigger: mapping() is called with an Iceberg Types.Type whose TypeID falls into the switch default — e.g. nested types not covered by the handled cases or unusual logical types reached recursively from struct/map/list fields.
Common situations: Iceberg tables with UUID, fixed(n), or time-type columns reached in nested positions; tables written by newer Iceberg writers with types added after this mapper was written; deep nested structs containing exotic leaf types.
Related errors
- Cannot convert date:
- Cannot convert time:
- Cannot convert timestamp: , type:
- Cannot convert timestamptz: , type:
- Cannot convert to BigDecimal:
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/f4e8e4b052117372.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/data/IcebergTypeMapper.java:80
}
// withoutZone() → NTZ → TIMESTAMP
return LocalTimeType.LOCAL_DATE_TIME_TYPE;
case STRING:
return BasicType.STRING_TYPE;
case FIXED:
case BINARY:
return PrimitiveByteArrayType.INSTANCE;
case DECIMAL:
Types.DecimalType decimalType = (Types.DecimalType) icebergType;
return new DecimalType(decimalType.precision(), decimalType.scale());
case STRUCT:
return mappingStructType((Types.StructType) icebergType);
case LIST:
return mappingListType(field, (Types.ListType) icebergType);
case MAP:
return mappingMapType(field, (Types.MapType) icebergType);
default:
throw CommonError.convertToSeaTunnelTypeError(
"Iceberg", icebergType.toString(), field);
}
}
private static SeaTunnelRowType mappingStructType(Types.StructType structType) {
List<Types.NestedField> fields = structType.fields();
List<String> fieldNames = new ArrayList<>(fields.size());
List<SeaTunnelDataType<?>> fieldTypes = new ArrayList<>(fields.size());
for (Types.NestedField field : fields) {
fieldNames.add(field.name());
fieldTypes.add(mapping(field.name(), field.type()));
}
return new SeaTunnelRowType(
fieldNames.toArray(new String[0]), fieldTypes.toArray(new SeaTunnelDataType[0]));
}
private static ArrayType mappingListType(String field, Types.ListType listType) {
switch (listType.elementType().typeId()) {View on GitHub (pinned to cf67b549a7)