{"record":{"id":"4393b0a28139483e","repo":"apache/seatunnel","slug":"failed-to-parse-offsetdatetime-value-class","errorCode":null,"errorMessage":"Failed to parse OffsetDateTime value:  (class: )","messagePattern":"Failed to parse OffsetDateTime value:  \\(class: \\)","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/utils/JdbcFieldTypeUtils.java","lineNumber":261,"sourceCode":"        // Fall back to ResultSet.getTimestamp() which the Oracle JDBC driver converts correctly.\n        String objClassName = obj.getClass().getName();\n        if (objClassName.equals(\"oracle.sql.TIMESTAMPLTZ\")\n                || objClassName.equals(\"oracle.sql.TIMESTAMPTZ\")) {\n            Timestamp oracleTs =\n                    resultSet.getTimestamp(\n                            columnIndex, Calendar.getInstance(TimeZone.getTimeZone(\"UTC\")));\n            if (oracleTs == null) {\n                return null;\n            }\n            return oracleTs.toInstant().atOffset(ZoneOffset.UTC);\n        }\n\n        // Try to parse as string\n        String str = obj.toString();\n        try {\n            return parseOffsetDateTimeFromString(str);\n        } catch (Exception e) {\n            throw new SQLException(\n                    \"Failed to parse OffsetDateTime value: \"\n                            + str\n                            + \" (class: \"\n                            + obj.getClass().getName()\n                            + \")\",\n                    e);\n        }\n    }\n\n    public static OffsetDateTime parseOffsetDateTimeFromString(String str)\n            throws DateTimeParseException {\n        String trimmed = str.trim();\n        // Treat empty string as \"no value\"\n        if (trimmed.isEmpty()) {\n            return null;\n        }\n        // Try parsing as standard ISO-8601 OffsetDateTime\n        OffsetDateTime directParsed = tryParseOffsetDateTime(trimmed);","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/utils/JdbcFieldTypeUtils.java#L243-L279","documentation":"JdbcFieldTypeUtils.getOffsetDateTime converts arbitrary JDBC objects to OffsetDateTime. When the object is not directly an OffsetDateTime/Timestamp, it stringifies it and tries to parse; a parse failure is wrapped in a SQLException carrying the string value and the source object's class. It means the driver returned a temporal type in a format the utility cannot interpret.","triggerScenarios":"Reading a column whose JDBC value is not OffsetDateTime and whose toString() (e.g. '2024-01-01 10:00:00' without offset, or a driver-specific format) cannot be parsed by parseOffsetDateTimeFromString; typically from TIMESTAMP WITH TIME ZONE or nonstandard vendor types.","commonSituations":"Drivers returning unusual string formats (MySQL 'YYYY-MM-DD HH:mm:ss', Oracle TIMESTAMP WITH LOCAL TIME ZONE); reading into Object mappings with getObject() on exotic types; schema drift where a column changed type.","solutions":["Check the value and class in the message to see the offending format, then adjust the query to CAST the column to a standard timestamp-with-time-zone type","Upgrade SeaTunnel or the JDBC driver — newer versions add more recognized formats","Add handling in JdbcFieldTypeUtils for the offending class/format if you control the build","Convert in the SQL (e.g. TO_TIMESTAMP_TZ / CONVERT_TZ) so the driver returns a parseable type"],"exampleFix":"// before\nSELECT ts FROM events // returns '2024-01-01 10:00:00' string-ish\n// after\nSELECT CAST(ts AS TIMESTAMP WITH TIME ZONE) AS ts FROM events","handlingStrategy":"type-guard","validationCode":"Object v = rs.getObject(col);\nif (!(v instanceof java.time.OffsetDateTime) && !(v instanceof java.sql.Timestamp)) {\n  log.warn(\"Column {} returns {} — add CAST to TIMESTAMP WITH TIME ZONE\", col, v.getClass().getName());\n}","typeGuard":"boolean isOffsetDateTimeSafe(Object o) {\n  return o instanceof java.time.OffsetDateTime || o instanceof java.sql.Timestamp;\n}","tryCatchPattern":"try {\n  OffsetDateTime odt = JdbcFieldTypeUtils.getOffsetDateTime(obj);\n} catch (SQLException e) {\n  if (e.getMessage().startsWith(\"Failed to parse OffsetDateTime value\")) {\n    log.warn(\"Falling back to Timestamp->toInstant conversion for value: {}\", e.getMessage());\n  }\n}","preventionTips":["CAST temporal columns to standard SQL timestamp-with-time-zone types","Pin driver versions with predictable getObject() mappings","Spot-check unusual columns' runtime classes before full runs"],"tags":["jdbc","datetime","parsing"],"backgroundTag":"invalid-date-format","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}