apache/seatunnel · error · ElasticsearchConnectorException
COMMON_UNSUPPORTED_OPERATION
COMMON_UNSUPPORTED_OPERATION
Error message
Unsupported type:
What it means
KeyExtractor formats primary-key fields into a string key for Elasticsearch document _id generation. Nested or collection types (ROW, ARRAY, MAP) cannot be rendered as a flat key string, so the library throws ElasticsearchConnectorException with UNSUPPORTED_OPERATION when a primary key column has one of those SQL types.
Source
Thrown at seatunnel-connectors-v2/connector-elasticsearch/src/main/java/org/apache/seatunnel/connectors/seatunnel/elasticsearch/serialize/KeyExtractor.java:77
List<FieldFormatter> fieldFormatters = new ArrayList<>(primaryKeys.length);
for (String fieldName : primaryKeys) {
int fieldIndex = rowType.indexOf(fieldName);
SeaTunnelDataType<?> fieldType = rowType.getFieldType(fieldIndex);
FieldFormatter fieldFormatter = createFieldFormatter(fieldIndex, fieldType);
fieldFormatters.add(fieldFormatter);
}
return new KeyExtractor(fieldFormatters.toArray(new FieldFormatter[0]), keyDelimiter);
}
private static FieldFormatter createFieldFormatter(
int fieldIndex, SeaTunnelDataType fieldType) {
return row -> {
switch (fieldType.getSqlType()) {
case ROW:
case ARRAY:
case MAP:
throw new ElasticsearchConnectorException(
CommonErrorCodeDeprecated.UNSUPPORTED_OPERATION,
"Unsupported type: " + fieldType);
case DATE:
LocalDate localDate = (LocalDate) row.getField(fieldIndex);
return localDate.toString();
case TIME:
LocalTime localTime = (LocalTime) row.getField(fieldIndex);
return localTime.toString();
case TIMESTAMP:
LocalDateTime localDateTime = (LocalDateTime) row.getField(fieldIndex);
return localDateTime.toString();
default:
return row.getField(fieldIndex).toString();
}
};
}
private interface FieldFormatter extends Serializable {View on GitHub (pinned to cf67b549a7)
Solutions
- Change the primary key column to a primitive scalar type (STRING, INT, LONG, etc.)
- If the key must come from a nested field, flatten it upstream with a transform (e.g. FieldMapper/Copy) and use the flattened scalar field as the primary key
- Cast or convert the key column to STRING in the source SQL/catalog before writing to Elasticsearch
Example fix
// before primaryKeys = ["user"] // user is ROW<id INT, name STRING> // after primaryKeys = ["user_id"] // user_id is a scalar STRING/INT field, extracted via transform
Defensive patterns
Strategy: validation
Validate before calling
for (String pk : primaryKeys) {
SeaTunnelDataType<?> t = rowType.getFieldType(rowType.indexOf(pk));
SqlType s = t.getSqlType();
if (s == SqlType.ROW || s == SqlType.ARRAY || s == SqlType.MAP) {
throw new IllegalArgumentException("Primary key field '" + pk + "' must be a scalar type, got " + s);
}
} Type guard
boolean isScalarKey(SeaTunnelDataType<?> t) {
SqlType s = t.getSqlType();
return s != SqlType.ROW && s != SqlType.ARRAY && s != SqlType.MAP;
} Prevention
- Declare only scalar primary-key columns for ES sinks
- Flatten nested fields with transforms before sink
- Add a startup schema check that validates key column types
When it happens
Trigger: Declaring a SeaTunnel table whose primary key (or index/`_id` key) column is of type ROW, ARRAY, or MAP; KeyExtractor.createFieldFormatter throws as soon as it builds the field formatter for that column.
Common situations: Source tables with composite/nested keys mapped to Elasticsearch sinks; CDC rows whose primary key is a struct; users assuming nested fields are flattened automatically for key extraction.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Unsupported type in LocalTimeArrayType: ${eleSqlType}
- Unsupported type: ${sqlType}
- Unsupported type: ${clazz}
- array inject error, unsupported data type: " + type
- UNSUPPORTED_TYPE
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/a910acdb957e7128.
Report an issue: GitHub.