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

  1. 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").
  2. 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.
  3. Check the WARN log line to see the exact offending source value and target type, then fix the source data or mapping.
  4. 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

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


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/9a47dec8bd7bcd7a. Report an issue: GitHub.