{"record":{"id":"74c9ff439d0e3ba6","repo":"apache/seatunnel","slug":"cannot-convert-timestamptz-type","errorCode":null,"errorMessage":"Cannot convert timestamptz: , type: ","messagePattern":"Cannot convert timestamptz: , type: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/data/RowConverter.java","lineNumber":441,"sourceCode":"\n    private OffsetDateTime convertOffsetDateTime(Object value) {\n        if (value instanceof Number) {\n            long millis = ((Number) value).longValue();\n            return DateTimeUtil.timestamptzFromMicros(millis * 1000);\n        } else if (value instanceof String) {\n            return parseOffsetDateTime((String) value);\n        } else if (value instanceof OffsetDateTime) {\n            return (OffsetDateTime) value;\n        } else if (value instanceof LocalDateTime) {\n            // Convert to OffsetDateTime using the system(jvm) default timezone\n            return ((LocalDateTime) value)\n                    .atZone(ZoneId.systemDefault())\n                    .withZoneSameInstant(ZoneOffset.UTC)\n                    .toOffsetDateTime();\n        } else if (value instanceof Date) {\n            return DateTimeUtil.timestamptzFromMicros(((Date) value).getTime() * 1000);\n        }\n        throw new RuntimeException(\n                \"Cannot convert timestamptz: \" + value + \", type: \" + value.getClass());\n    }\n\n    private OffsetDateTime parseOffsetDateTime(String str) {\n        String tsStr = ensureTimestampFormat(str);\n        try {\n            return OFFSET_TS_FMT.parse(tsStr, OffsetDateTime::from);\n        } catch (DateTimeParseException e) {\n            return LocalDateTime.parse(tsStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME)\n                    .atOffset(ZoneOffset.UTC);\n        }\n    }\n\n    private LocalDateTime convertLocalDateTime(Object value) {\n        if (value instanceof Number) {\n            long millis = ((Number) value).longValue();\n            return DateTimeUtil.timestampFromMicros(millis * 1000);\n        } else if (value instanceof String) {","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/data/RowConverter.java#L423-L459","documentation":"Iceberg RowConverter throws this RuntimeException when a timestamptz (Iceberg TimestampType with adjustToUTC) value cannot be converted to OffsetDateTime. convertOffsetDateTime accepts String (parsed), LocalDateTime, OffsetDateTime, and Date; anything else is rejected with both value and class in the message.","triggerScenarios":"convertOffsetDateTime receives an unsupported object (e.g. Long epoch millis, ZonedDateTime, or a nested type) while converting a field for a timestamptz Iceberg column via convertTimestampValue.","commonSituations":"Sources emitting epoch millis as Long for timestamp columns; JDBC sources returning custom temporal types; CDC formats delivering timestamps in wrapper objects.","solutions":["Convert the value to OffsetDateTime or java.util.Date before the sink.","Add a transform CAST(column, TIMESTAMP) so SeaTunnel delivers a supported temporal type.","If holding epoch millis, convert: Instant.ofEpochMilli(ms).atOffset(ZoneOffset.UTC).","Check source connector timestamp mapping config so timestamps arrive as SeaTunnel TimestampType."],"exampleFix":"// before\nwriter.write(idx, 1710000000000L); // Long not accepted\n// after\nwriter.write(idx, Instant.ofEpochMilli(1710000000000L).atOffset(ZoneOffset.UTC)); // OffsetDateTime accepted","handlingStrategy":"type-guard","validationCode":"if (!(v instanceof OffsetDateTime) && !(v instanceof LocalDateTime) && !(v instanceof java.util.Date) && !(v instanceof String)) throw new IllegalArgumentException(\"timestamptz column must be OffsetDateTime/LocalDateTime/Date/String, got \" + (v == null ? \"null\" : v.getClass().getName()));","typeGuard":"boolean isTimestamptzConvertible(Object v) { return v instanceof OffsetDateTime || v instanceof LocalDateTime || v instanceof java.util.Date || v instanceof String; }","tryCatchPattern":"try { sink.write(row); } catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().startsWith(\"Cannot convert timestamptz\")) { /* convert epoch/Instant to OffsetDateTime or DLQ */ } else throw e; }","preventionTips":["Convert epoch millis/Instant to OffsetDateTime before the sink","Map source timestamps to SeaTunnel TimestampType","Verify timestamp column type is not a Long in the SeaTunnel catalog table"],"tags":["iceberg","type-conversion","timestamp","timestamptz"],"backgroundTag":"type-mismatch","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}