{"record":{"id":"2980bb1fab2e788f","repo":"apache/iceberg","slug":"unexpected-object-type-for-timestamp-logical-type","errorCode":null,"errorMessage":"Unexpected object type for TIMESTAMP logical type. Received: ${object}","messagePattern":"Unexpected object type for TIMESTAMP logical type\\. Received: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/formats/avro/AvroToRowDataConverters.java","lineNumber":251,"sourceCode":"        return TimestampData.fromEpochMillis(timeLong);\n      } else if (precision <= 6) {\n        return TimestampData.fromEpochMillis(\n            Math.floorDiv(timeLong, 1000L), (int) Math.floorMod(timeLong, 1000L) * 1000);\n      } else {\n        // Iceberg: Added support for nanoseconds precision (FLINK-39251)\n        return TimestampData.fromEpochMillis(\n            Math.floorDiv(timeLong, 1_000_000L), (int) Math.floorMod(timeLong, 1_000_000L));\n      }\n    } else if (object instanceof Instant) {\n      return TimestampData.fromInstant((Instant) object);\n    } else if (object instanceof LocalDateTime) {\n      return TimestampData.fromLocalDateTime((LocalDateTime) object);\n    } else {\n      JodaConverter jodaConverter = JodaConverter.getConverter();\n      if (jodaConverter != null) {\n        return TimestampData.fromEpochMillis(jodaConverter.convertTimestamp(object));\n      } else {\n        throw new IllegalArgumentException(\n            \"Unexpected object type for TIMESTAMP logical type. Received: \" + object);\n      }\n    }\n  }\n\n  private static int convertToDate(Object object) {\n    if (object instanceof Integer) {\n      return (Integer) object;\n    } else if (object instanceof LocalDate) {\n      return (int) ((LocalDate) object).toEpochDay();\n    } else {\n      JodaConverter jodaConverter = JodaConverter.getConverter();\n      if (jodaConverter != null) {\n        return (int) jodaConverter.convertDate(object);\n      } else {\n        throw new IllegalArgumentException(\n            \"Unexpected object type for DATE logical type. Received: \" + object);\n      }","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/formats/avro/AvroToRowDataConverters.java#L233-L269","documentation":"convertToTimestamp converts an Avro field value for a TIMESTAMP logical type into Flink TimestampData. It accepts LocalDateTime, java.util.Date/Instant via Joda bridge, etc.; when the object is none of the expected classes (and no Joda converter is available) it throws IllegalArgumentException reporting the actual object's toString.","triggerScenarios":"Avro record contains a value under a timestamp logical-type field whose Java class is neither LocalDateTime nor a type handled by JodaConverter — typically a Long in legacy micros read with non-legacy converter expectations, or vice versa.","commonSituations":"Mismatch between the table's avro timestamp mapping property and the actual Avro file contents (files written with legacy Long encoding read via the modern converter); schema evolution changing field encoding without rewriting files.","solutions":["Align the table's avro timestamp-mapping property with how the data files were actually written (rewrite files with the Spark/Avro rewrite procedure if mismatched).","Check the 'Received:' value in the message to identify the actual Java class and adjust the reader/converter for that class.","Upgrade or downgrade the iceberg-flink version so the converter matches the file's logical-type encoding (FLINK-39251 nanosecond support changed expectations).","Pre-convert the field: wrap the raw object into LocalDateTime before it reaches the Avro→RowData converter (custom converter via createConverter overloads)."],"exampleFix":"// before\nObject avroValue = record.get(\"ts\"); // java.time.Instant (not LocalDateTime)\nRowData row = converter.convert(record); // throws\n// after\nrecord.put(\"ts\", LocalDateTime.ofInstant((Instant) avroValue, ZoneOffset.UTC));\nRowData row = converter.convert(record);","handlingStrategy":"validation","validationCode":"Object v = record.get(\"ts\");\nif (!(v instanceof LocalDateTime) && !jodaSupported(v)) { throw new IllegalArgumentException(\"ts has unexpected class: \" + v.getClass()); }","typeGuard":"boolean isSupportedTimestamp(Object v) { return v instanceof LocalDateTime || v instanceof org.joda.time.DateTime || v instanceof java.util.Date; }","tryCatchPattern":"try { return convertToTimestamp(obj, type); } catch (IllegalArgumentException e) { return TimestampData.fromLocalDateTime(toLocalDateTime(obj)); }","preventionTips":["Keep the avro timestamp-mapping property consistent with how files were written","Rewrite files after changing timestamp mapping properties","Ensure joda-time is on the classpath when reading legacy files","Verify the actual class of timestamp values in Avro files when upgrading readers"],"tags":["flink","avro","timestamp","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}