apache/seatunnel · error · java.lang.IllegalArgumentException

Unable to convert to LocalDateTime from unexpected value ''

Error message

Unable to convert to LocalDateTime from unexpected value '' of type 

What it means

The TIMESTAMP converter in SeaTunnelRowDebeziumDeserializationConverters accepts numeric epoch values or ISO-8601 instant strings. Any other object type (e.g. java.util.Date, Timestamp in unexpected form) reaches the IllegalArgumentException 'Unable to convert to LocalDateTime from unexpected value ... of type ...', which reports the value and its Java class.

Source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/debezium/row/SeaTunnelRowDebeziumDeserializationConverters.java:575

        LocalDate localDate = LocalDate.ofEpochDay(date);
        LocalTime localTime = LocalTime.ofNanoOfDay(nanoOfDay);
        return LocalDateTime.of(localDate, localTime);
    }

    private static DebeziumDeserializationConverter convertToLocalTimeZoneTimestamp(
            ZoneId serverTimeZone) {
        return new DebeziumDeserializationConverter() {
            private static final long serialVersionUID = 1L;

            @Override
            public Object convert(Object dbzObj, Schema schema) {
                if (dbzObj instanceof String) {
                    String str = (String) dbzObj;
                    // TIMESTAMP type is encoded in string type
                    Instant instant = Instant.parse(str);
                    return LocalDateTime.ofInstant(instant, serverTimeZone);
                }
                throw new IllegalArgumentException(
                        "Unable to convert to LocalDateTime from unexpected value '"
                                + dbzObj
                                + "' of type "
                                + dbzObj.getClass().getName());
            }
        };
    }

    private static DebeziumDeserializationConverter convertToString() {
        return new DebeziumDeserializationConverter() {
            private static final long serialVersionUID = 1L;

            @Override
            public Object convert(Object dbzObj, Schema schema) {
                if (dbzObj == null) {
                    return null;
                }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check the class name in the message and add/enable the appropriate value converter (e.g. TimestampConverter) so Debezium emits epoch micros or ISO strings.
  2. Pre-normalize strings to ISO-8601 Instant format (e.g. '2024-01-01T10:00:00Z') via a transform or source-side formatting.
  3. Fix invalid source timestamp values that fail Instant.parse, or map the column to STRING in the schema and parse downstream.

Example fix

// before
// value '2024-01-01 10:00:00' (no T/Z) -> IllegalArgumentException
// after
// value '2024-01-01T10:00:00Z' parses as Instant and converts
Defensive patterns

Strategy: type-guard

Validate before calling

// Java
static boolean isConvertibleToTimestamp(Object v) {
    return v instanceof Number
        || (v instanceof String && canParseInstant((String) v));
}
static boolean canParseInstant(String s) {
    try { Instant.parse(s); return true; } catch (Exception e) { return false; }
}

Type guard

if (!(dbzObj instanceof Number) && !(dbzObj instanceof String)) {
    log.warn("TIMESTAMP value of type {} will be rejected; convert to epoch micros or ISO string first", dbzObj.getClass());
}

Try / catch

try {
    ldt = timestampConverter.convert(dbzObj);
} catch (IllegalArgumentException e) {
    log.warn("bad TIMESTAMP value {} ({}), mapping to null", dbzObj, dbzObj.getClass(), e);
    ldt = null;
}

Prevention

When it happens

Trigger: convert() for TIMESTAMP receives a dbzObj that is neither Long/Integer epoch micros nor a parseable String Instant — e.g. a java.sql.Timestamp, java.util.Date, or an unparseable string.

Common situations: Database driver/Debezium converter returning Date-like objects instead of the expected epoch long or ISO string; malformed timestamp strings (not Instant.parse-able) such as '2024-01-01 10:00:00' without T/Z.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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