apache/seatunnel · error · SQLException

Failed to parse PostgreSQL timestamptz string: ${str}

Error message

Failed to parse PostgreSQL timestamptz string: ${str}

What it means

Thrown by parsePostgresTimestampTz when a PostgreSQL timestamptz string value cannot be converted to an OffsetDateTime, after a fallback attempt to parse it as a UTC timestamp also failed. The original string and the secondary exception are attached as the cause so the offending value can be inspected.

Source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/psql/PostgresJdbcRowConverter.java:442

            return null;
        }

        try {
            return OffsetDateTime.parse(normalized);
        } catch (Exception primary) {
            log.debug("Failed to parse PostgreSQL timestamptz as ISO-8601: {}", str, primary);
            try {
                String withoutOffset =
                        normalized.replaceFirst("([+-]\\d{2}:?\\d{2}|\\s+UTC|[zZ])$", "");
                String fallback = withoutOffset.replace('T', ' ').trim();
                Timestamp ts = Timestamp.valueOf(fallback);
                return ts.toInstant().atOffset(ZoneOffset.UTC);
            } catch (Exception secondary) {
                log.debug(
                        "Failed to parse PostgreSQL timestamptz as UTC timestamp: {}",
                        str,
                        secondary);
                throw new SQLException(
                        "Failed to parse PostgreSQL timestamptz string: " + str, secondary);
            }
        }
    }

    @Nullable private OffsetDateTime parseTimestampFromObjectString(Object obj) throws SQLException {
        final String str;
        try {
            str = String.valueOf(obj);
        } catch (Throwable e) {
            log.debug(
                    "Failed to get PostgreSQL timestamp object string representation from class: {}",
                    obj.getClass().getName(),
                    e);
            return null;
        }
        return parsePostgresTimestampTz(str);
    }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check the actual string value in the exception message and compare it against ISO-8601 expectations
  2. Set the session datestyle/timezone explicitly (e.g. SET datestyle='ISO') on the PostgreSQL connection so the driver returns parseable strings
  3. Upgrade the PostgreSQL JDBC driver so timestamptz columns come back as OffsetDateTime/Timestamp objects instead of Strings
  4. Pre-cast the column in the SQL query: CAST(col AS text) with an explicit format, or select via to_char(col, 'YYYY-MM-DD"T"HH24:MI:SSOF')

Example fix

// before
String raw = rs.getString("created_at");
// after
OffsetDateTime odt = rs.getObject("created_at", OffsetDateTime.class); // avoid string parsing path
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate string before relying on connector parsing
boolean parseable;
try {
    java.time.OffsetDateTime.parse(str);
    parseable = true;
} catch (java.time.format.DateTimeParseException e) {
    parseable = false;
}

Type guard

static boolean isIsoTimestamptz(String s) {
    return s != null && java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(s, java.time.temporal.TemporalQueries.offset()) != null;
}

Try / catch

try {
    runJob();
} catch (SQLException e) {
    if (e.getMessage().startsWith("Failed to parse PostgreSQL timestamptz string:")) {
        // log raw value from message, fix session datestyle or pre-format column
    }
}

Prevention

When it happens

Trigger: Reading a timestamptz column via parseTimestampFromObjectString when the JDBC driver returns the value as a String in a format the parser does not recognize (e.g. non-ISO date formats, unusual timezone offsets, or pre-1970 dates before PostgreSQL epoch handling).

Common situations: Servers with non-default datestyle/timezone settings producing localized timestamp strings; legacy PostgreSQL versions or drivers returning odd string representations; data migrated with non-standard timestamp formats.

Understand the failure class

Related errors


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