apache/seatunnel · warning
convert target data type error. source:{}, targetType:{}
Error message
convert target data type error. source:{}, targetType:{} What it means
In Apache SeaTunnel's SensorsData connector, TypeUtil.toTimestamp() converts a field value to an epoch-millisecond timestamp for the SensorsData (zhugeio) inf-sdk. When the source value cannot be interpreted as a Date, Number, LocalDate, LocalDateTime, or a date string matching one of the supported formatters (or a custom `extra` pattern), the conversion fails. This is NOT an exception: the method logs 'convert target data type error. source:{}, targetType:{}' at WARN level and returns the original value unchanged, so the field is sent to SensorsData with its raw, unconverted type.
Source
Thrown at seatunnel-connectors-v2/connector-sensorsdata/src/main/java/org/apache/seatunnel/connectors/sensorsdata/format/utils/TypeUtil.java:183
if (source instanceof LocalDateTime) {
return ((LocalDateTime) source)
.atZone(ZoneId.systemDefault())
.toInstant()
.toEpochMilli();
}
if (source instanceof String) {
Long timestamp;
if (format == null) {
timestamp = tryParse((String) source);
} else {
DateTimeFormatter formatter = parseDateTimeFormatter(format);
timestamp = tryParse((String) source, formatter);
}
if (timestamp != null) {
return timestamp;
}
}
log.warn(TRANSFORM_WARN_INFO, source, targetType);
return source;
}
private static Object toBoolean(Object source, SensorsDataTypes.DataTypes targetType) {
if (source instanceof Boolean) {
return source;
}
if (source instanceof Number) {
return !Objects.equal(0, source)
&& !Objects.equal(0F, source)
&& !Objects.equal(0D, source)
&& !Objects.equal(0L, source);
}
if (source instanceof String) {
return StringUtils.equalsIgnoreCase("true", source.toString());
}
log.warn(TRANSFORM_WARN_INFO, source, targetType);
return source;View on GitHub (pinned to cf67b549a7)
Solutions
- Set the TIMESTAMP column's extra format option in the connector schema to a DateTimeFormatter pattern matching your data (e.g. "yyyy-MM-dd'T'HH:mm:ssXXX").
- Normalize the date string upstream (transform) into one of the supported patterns: yyyy-MM-dd HH:mm:ss, yyyy-MM-dd HH:mm:ss.SSS, yyyy-MM-dd, yyyyMMdd_HHmmss, yyyyMMdd, or yyyy-MM-dd HH:mm.
- Check the WARN log line to see the exact offending source value and target type, then fix the source data or mapping.
- If the field is not really a timestamp, change the schema type to STRING so no conversion is attempted.
Example fix
// before: schema maps event_time as TIMESTAMP but data is ISO-8601
// 2024-01-15T10:30:00Z -> conversion fails, value passed through as String
// after: declare the extra format for the TIMESTAMP field
// fields { event_time = TIMESTAMP }
// with extra format option set to:
// "yyyy-MM-dd'T'HH:mm:ssXXX"
// or pre-normalize the value: 2024-01-15 10:30:00 Defensive patterns
Strategy: validation
Validate before calling
// Java: verify before writing a TIMESTAMP field
private static boolean isValidTimestamp(Object v) {
return v instanceof java.util.Date
|| v instanceof Number
|| v instanceof java.time.LocalDate
|| v instanceof java.time.LocalDateTime
|| (v instanceof String s && !s.isBlank() && TypeUtil.tryParsePatterns(s)); // matches yyyy-MM-dd[ HH:mm:ss[.SSS]] etc.
}
// call: if (!isValidTimestamp(value)) { normalize(value); } Type guard
private static boolean isTimestampConvertible(Object v) {
if (v == null) return true; // null short-circuits in toTargetType
return v instanceof java.util.Date || v instanceof Number
|| v instanceof java.time.LocalDate || v instanceof java.time.LocalDateTime
|| (v instanceof String && v.toString().matches("\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2}(\\.\\d{3})?)?)?|\\d{8}(_\\d{6})?"));
} Prevention
- Always declare the extra format pattern for TIMESTAMP columns whose data is not in a supported default pattern.
- Pre-normalize ISO-8601 ('T'-separated, timezone-suffixed) dates before ingest.
- Grep connector logs for 'convert target data type error' after pipeline changes to catch silently passed-through fields.
- Validate sample source records against the formatter patterns before running full jobs.
When it happens
Trigger: TypeUtil.toTimestamp(source, TIMESTAMP, extra) is reached via toTargetType() when the schema maps a column to TIMESTAMP but the runtime value is a String that matches none of the internal patterns (yyyy-MM-dd HH:mm:ss.SSS, yyyy-MM-dd HH:mm:ss, yyyy-MM-dd HH:mm, yyyy-MM-dd, yyyyMMdd_HHmmss, yyyyMMdd) nor the custom `extra` DateTimeFormatter pattern; e.g. an ISO-8601 string like '2024-01-15T10:30:00Z' or a locale-formatted date.
Common situations: Upstream data (CSV/JSON/Kafka) carries dates in ISO-8601 or RFC-3339 format with 'T' separator or timezone suffix, which the hardcoded SeaTunnel formatters do not accept; user forgets to set the TIMESTAMP extra format option; source column is empty or contains 'N/A'/'null' strings; timezone/locale differences shift the expected pattern.
Related errors
- DATA_TYPE_CAST_FIELD
- COMMON-17
- Unsupported convert %s to %s
- Unsupported convert ${value.getClass()} to LocalTime, typeDe
- Unsupported convert ${value.getClass()} to LocalTime
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/9a47dec8bd7bcd7a.
Report an issue: GitHub.