apache/seatunnel · error · IotdbConnectorException
CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT
CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT
Error message
Illegal SeaTunnelRowType: {rowRecord} What it means
DefaultSeaTunnelRowDeserializer.convert() builds a SeaTunnelRow from an IoTDB RowRecord and expects the row type to have exactly one more column (the timestamp) than the number of fields in the IoTDB record. When fields.size() != rowType.getTotalFields() - 1, the schema configured for the source does not match the data IoTDB returns, so it throws ILLEGAL_ARGUMENT.
Source
Thrown at seatunnel-connectors-v2/connector-iotdb/src/main/java/org/apache/seatunnel/connectors/seatunnel/iotdb/serialize/DefaultSeaTunnelRowDeserializer.java:49
import java.time.ZoneOffset;
import java.util.Date;
import java.util.List;
@AllArgsConstructor
public class DefaultSeaTunnelRowDeserializer implements SeaTunnelRowDeserializer {
private final SeaTunnelRowType rowType;
@Override
public SeaTunnelRow deserialize(RowRecord rowRecord) {
return convert(rowRecord);
}
private SeaTunnelRow convert(RowRecord rowRecord) {
long timestamp = rowRecord.getTimestamp();
List<Field> fields = rowRecord.getFields();
if (fields.size() != (rowType.getTotalFields() - 1)) {
throw new IotdbConnectorException(
CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT,
"Illegal SeaTunnelRowType: " + rowRecord);
}
Object[] seaTunnelFields = new Object[rowType.getTotalFields()];
seaTunnelFields[0] = convertTimestamp(timestamp, rowType.getFieldType(0));
for (int i = 1; i < rowType.getTotalFields(); i++) {
Field field = fields.get(i - 1);
if (field == null || field.getDataType() == null) {
seaTunnelFields[i] = null;
continue;
}
SeaTunnelDataType<?> seaTunnelFieldType = rowType.getFieldType(i);
seaTunnelFields[i] = convert(seaTunnelFieldType, field);
}
return new SeaTunnelRow(seaTunnelFields);
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Re-read the table so the SeaTunnelRowType is resolved against the current IoTDB schema; avoid wildcard queries whose result columns can drift
- Compare the configured column list with 'SHOW DEVICES' / 'SHOW TIMESERIES' output and align them exactly (timestamp column + N measurements)
- Pin the query to an explicit field list instead of ** so schema drift cannot change the field count
- Upgrade the connector/catalog if IoTDB metadata changes are frequent; re-run job after schema changes
Example fix
// before (wildcard query that drifts) query = "select ** from root.db.device1" // after (explicit fields matching configured rowType) query = "select s_temperature, s_humidity from root.db.device1"
Defensive patterns
Strategy: validation
Validate before calling
// before running the job, compare field counts
// SeaTunnelRowType rowType; RowRecord rec;
if (rec.getFields().size() != rowType.getTotalFields() - 1) {
throw new IllegalStateException("Schema drift: IoTDB returned " + rec.getFields().size()
+ " fields, schema expects " + (rowType.getTotalFields() - 1));
} Type guard
boolean schemaMatches(RowRecord rec, SeaTunnelRowType rowType) {
return rec.getFields().size() == rowType.getTotalFields() - 1;
} Try / catch
try {
SeaTunnelRow row = deserializer.deserialize(record);
} catch (IotdbConnectorException e) {
if (e.getCode() == CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT) {
// re-resolve catalog schema and restart
} else { throw e; }
} Prevention
- Use explicit measurement lists in queries instead of wildcards (select **)
- Re-resolve the catalog schema after any IoTDB DDL change
- Pin the IoTDB schema version used by long-running jobs
When it happens
Trigger: Calling convert(RowRecord) where the number of measurement fields in the IoTDB RowRecord does not equal rowType.getTotalFields() minus 1 — i.e. the configured SeaTunnelRowType (from the query/schema) diverges from the actual IoTDB timeseries fields.
Common situations: IoTDB schema evolved (measurements added/removed or a wildcard query like select ** from ...) after the catalog/table schema was resolved; alignment on the wrong device; query pattern mismatch with configured field list; catalog plugin resolved stale metadata.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Fail to deserialize row: ${row}, table: ${tableInfo.getId()}
- COMMON_UNSUPPORTED_OPERATION
- ILLEGAL_ARGUMENT
- UNSUPPORTED_DATA_TYPE
- CommonErrorCodeDeprecated.UNSUPPORTED_DATA_TYPE
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/e6febc6d5cc944c9.
Report an issue: GitHub.