apache/seatunnel · error · ElasticsearchConnectorException
COMMON_UNSUPPORTED_OPERATION
COMMON_UNSUPPORTED_OPERATION
Error message
Unsupported write row kind:
What it means
ElasticsearchRowSerializer.serializeRow throws COMMON_UNSUPPORTED_OPERATION when the incoming SeaTunnelRow has a RowKind the serializer cannot handle. Only INSERT/UPDATE_AFTER (upsert), UPDATE_BEFORE and DELETE are supported; anything else (e.g., INSERT arriving on an upsert path is fine, but kinds outside the switch) fails with 'Unsupported write row kind: <kind>'.
Source
Thrown at seatunnel-connectors-v2/connector-elasticsearch/src/main/java/org/apache/seatunnel/connectors/seatunnel/elasticsearch/serialize/ElasticsearchRowSerializer.java:97
this.seaTunnelRowType = seaTunnelRowType;
this.keyExtractor =
KeyExtractor.createKeyExtractor(
seaTunnelRowType, indexInfo.getPrimaryKeys(), indexInfo.getKeyDelimiter());
this.vectorizationFields = vectorizationFields;
this.vectorDimension = vectorDimension;
}
@Override
public String serializeRow(SeaTunnelRow row) {
switch (row.getRowKind()) {
case INSERT:
case UPDATE_AFTER:
return serializeUpsert(row);
case UPDATE_BEFORE:
case DELETE:
return serializeDelete(row);
default:
throw new ElasticsearchConnectorException(
CommonErrorCodeDeprecated.UNSUPPORTED_OPERATION,
"Unsupported write row kind: " + row.getRowKind());
}
}
private String serializeUpsert(SeaTunnelRow row) {
String key = keyExtractor.apply(row);
Map<String, Object> document = toDocumentMap(row, seaTunnelRowType);
String documentStr;
try {
documentStr = objectMapper.writeValueAsString(document);
} catch (JsonProcessingException e) {
throw CommonError.jsonOperationError(
"Elasticsearch", "document:" + document.toString(), e);
}
if (key != null) {View on GitHub (pinned to cf67b549a7)
Solutions
- Check the RowKind printed in the message and trace which upstream operator emits it
- Convert/normalize row kinds upstream (e.g., map INSERT to UPDATE_AFTER for upsert-based writing, or filter UPDATE_BEFORE)
- If writing plain batch data, ensure the sink is configured for insert/upsert semantics so INSERT rows take the serializeUpsert path
- For CDC sources, keep DELETE/UPDATE_BEFORE kinds intact or drop them depending on desired delete semantics
Example fix
// before // emitting RowKind.INSERT rows into a CDC upsert pipeline // after row.setRowKind(RowKind.UPDATE_AFTER); // normalize before the sink
Defensive patterns
Strategy: validation
Validate before calling
// Filter or normalize row kinds before the sink:
switch (row.getRowKind()) {
case INSERT:
case UPDATE_AFTER:
case UPDATE_BEFORE:
case DELETE: break; // supported
default: throw new IllegalStateException("Unsupported RowKind for ES sink: " + row.getRowKind());
} Type guard
boolean isWritableRowKind(SeaTunnelRow row) {
RowKind k = row == null ? null : row.getRowKind();
return k == RowKind.INSERT || k == RowKind.UPDATE_AFTER || k == RowKind.UPDATE_BEFORE || k == RowKind.DELETE;
} Try / catch
try {
String json = ElasticsearchRowSerializer.serializeRow(row);
} catch (ElasticsearchConnectorException e) {
if (String.valueOf(e.getMessage()).startsWith("Unsupported write row kind")) {
log.warn("Skipping row with kind {}", row.getRowKind());
return;
}
throw e;
} Prevention
- Normalize INSERT to UPDATE_AFTER when feeding upsert-style writes
- Drop or handle UPDATE_BEFORE explicitly if deletes are not needed
- Avoid custom transforms that emit exotic RowKinds into the ES sink
- Assert row kinds in unit tests for CDC pipelines
When it happens
Trigger: Writing rows whose RowKind falls into the switch's default branch — e.g., a sink receiving RowKind.INSERT on a path expecting only CDC-updated rows, or a custom/transformed stream emitting unusual row kinds to the Elasticsearch sink.
Common situations: CDC pipelines where upstream emits kinds the Elasticsearch sink does not map; mixing batch (INSERT-only) data with CDC expectations; a transform upstream changing row kinds unexpectedly.
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
- Unrecognized row kind:<rowKind>
- UNSUPPORTED_OPERATION
- UNSUPPORTED_OPERATION
- UNSUPPORTED_OPERATION
- COMMON_UNSUPPORTED_OPERATION
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/b3ac6e5f6192836b.
Report an issue: GitHub.