apache/seatunnel · error · java.lang.IllegalArgumentException
Unable to parse OffsetDateTime from CDC TIMESTAMP_TZ value:
Error message
Unable to parse OffsetDateTime from CDC TIMESTAMP_TZ value: ''. Supported formats: ISO-8601 with numeric offset, IANA zone-region id, space-separated date/time, short-form hour-only offset, UTC epoch literal.
What it means
parseOffsetDateTimeFromString() converts a CDC TIMESTAMP_TZ string value to an OffsetDateTime. It tries multiple formats: ISO-8601 with offset, IANA region id, space-separated datetime, short hour-only offset, and Instant/epoch literal. When the string matches none, it throws IllegalArgumentException listing all supported formats.
Source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/debezium/row/SeaTunnelRowDebeziumDeserializationConverters.java:514
// fall through
}
// 3. Space separator or short offset: 2024-01-01 12:00:00+08:00 / +08
try {
return java.time.OffsetDateTime.parse(str, FLEXIBLE_OFFSET_FORMATTER)
.withOffsetSameInstant(java.time.ZoneOffset.UTC);
} catch (java.time.format.DateTimeParseException ignored) {
// fall through
}
// 4. UTC epoch literal: 2024-01-01T12:00:00Z
try {
return Instant.parse(str).atOffset(java.time.ZoneOffset.UTC);
} catch (java.time.format.DateTimeParseException ignored) {
// fall through
}
throw new IllegalArgumentException(
"Unable to parse OffsetDateTime from CDC TIMESTAMP_TZ value: '"
+ str
+ "'. Supported formats: ISO-8601 with numeric offset, IANA zone-region"
+ " id, space-separated date/time, short-form hour-only offset, UTC"
+ " epoch literal.");
}
private static DebeziumDeserializationConverter convertToTimestamp(ZoneId serverTimeZone) {
return new DebeziumDeserializationConverter() {
private static final long serialVersionUID = 1L;
@SuppressWarnings("MagicNumber")
@Override
public Object convert(Object dbzObj, Schema schema) {
if (dbzObj instanceof Long) {
switch (schema.name()) {
case Timestamp.SCHEMA_NAME:
return toLocalDateTime((Long) dbzObj, 0);View on GitHub (pinned to cf67b549a7)
Solutions
- Fix the source data: replace empty/zero-date timestamp values with valid timestamps (e.g. NULL or a sentinel like '1970-01-01T00:00:00Z').
- Ensure the column produces ISO-8601 or IANA-zone formatted values; add a converter/transform to normalize before deserialization.
- Check the exact offending value in the message; if it is a legitimate new format, extend the parser chain in SeaTunnelRowDebeziumDeserializationConverters.
Example fix
// before // source contains '' or '0000-00-00 00:00:00' for TIMESTAMP_TZ // after UPDATE t SET ts = NULL WHERE ts = '0000-00-00 00:00:00'; // or configure the job to map invalid dates to null/sentinel
Defensive patterns
Strategy: validation
Validate before calling
// Java: pre-validate CDC timestamp strings
static boolean isParsableTimestampTz(String s) {
if (s == null || s.isEmpty()) return false;
try { OffsetDateTime.parse(s); return true; } catch (Exception ignored) {}
try { ZoneId.of(s); return true; } catch (Exception ignored) {}
try { Instant.parse(s); return true; } catch (Exception ignored) {}
return s.matches("[+-]\\d{2}(:?\\d{2})?") || s.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}(:\\d{2})?");
} Type guard
if (v == null || (v instanceof String && ((String) v).trim().isEmpty())) {
return null; // treat empty TIMESTAMP_TZ as null before parsing
} Try / catch
try {
odt = parseOffsetDateTimeFromString(str);
} catch (IllegalArgumentException e) {
log.warn("unparseable TIMESTAMP_TZ '{}', substituting null/sentinel", str);
odt = null;
} Prevention
- Scrub zero-date/empty timestamp values at the source (e.g. MySQL sql_mode NO_ZERO_DATE, NULL instead of '0000-00-00')
- Emit TIMESTAMP_TZ in ISO-8601 or IANA zone form from producers
- Add a job-level transform to normalize or null-out invalid datetimes before deserialization
When it happens
Trigger: A TIMESTAMP_TZ CDC value that is empty, null-rendered as '', or formatted in a non-ISO layout (e.g. custom driver string or locale-dependent text) reaches convert() -> parseOffsetDateTimeFromString().
Common situations: Empty string timestamps from some database drivers or placeholder values (e.g. '0000-00-00 00:00:00' style zero dates from MySQL), or a date-time format not covered by the parser branches.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unable to convert to LocalDateTime from unexpected value ''
- Unable to convert to LocalDate from a java.sql.Time value '
- not supported create new Offset by timestamp.
- Convert timestamp to LSN offset error
- No LSN found for timestamp %d (%s)
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/969b95da03453ea3.
Report an issue: GitHub.