{"record":{"id":"401b06147afd8a66","repo":"apache/iceberg","slug":"unexpected-object-type-for-timestamp-logical-type-401b06","errorCode":null,"errorMessage":"Unexpected object type for TIMESTAMP logical type. Received: ${object}","messagePattern":"Unexpected object type for TIMESTAMP logical type\\. Received: (.+?)","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink/v2.1/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/v2.1/flink/src/main/java/org/apache/iceberg/flink/formats/avro/AvroToRowDataConverters.java#L233-L269","documentation":"Thrown by AvroToRowDataConverters.convertToTimestamp when an Avro 'timestamp-millis'/'timestamp-micros' logical type field yields an object that is neither java.time.LocalDateTime nor a type supported by the Joda converter. The converter cannot map the runtime object to Flink TimestampData, so it fails fast with the offending object in the message.","triggerScenarios":"Reading Avro data whose timestamp field deserialized to an unexpected type (e.g. java.util.Date, Long, org.joda.time.DateTime when Joda classes are absent from the classpath so JodaConverter.getConverter() returns null).","commonSituations":"Avro files written by frameworks that materialize timestamps as java.util.Date or epoch Long; running Flink 1.9+ (java.time default mapping) against records produced with the legacy Joda mapping without joda-time on the classpath.","solutions":["Add the joda-time dependency so JodaConverter can convert legacy objects, or re-register the Avro reader schema with a java.time-compatible value class","Ensure the Avro specific/reflect record maps timestamp logical types to LocalDateTime (configure the reflect data model to use java.time)","Convert the field yourself with a custom DatumReader/Conversion so the object reaching the converter is LocalDateTime","Check the reader schema matches the writer schema's logical types"],"exampleFix":"// before (joda-time missing, legacy data)\nObject obj = record.get(\"ts\"); // java.util.Date\n// after: add joda-time to the classpath or convert first\nTimestampData ts = TimestampData.fromLocalDateTime(\n    LocalDateTime.ofInstant(((java.util.Date) obj).toInstant(), ZoneOffset.UTC));","handlingStrategy":"type-guard","validationCode":"Object ts = record.get(\"ts\");\nif (!(ts instanceof LocalDateTime) && !(ts instanceof java.util.Date) && !(ts instanceof Long)) {\n  throw new IllegalStateException(\"Unexpected timestamp type: \" + ts.getClass());\n}","typeGuard":"boolean isSupportedTimestamp(Object o) {\n  return o instanceof LocalDateTime || o instanceof java.util.Date || o instanceof Long;\n}","tryCatchPattern":"try {\n  RowData row = converter.convert(record);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Unexpected object type for TIMESTAMP\")) {\n    // normalize the object and retry\n  } else { throw e; }\n}","preventionTips":["Keep joda-time on the classpath when consuming legacy Avro data","Align reader/writer Avro schemas and logical type conversions","Prefer specific records generated with java.time mappings","Validate sample records' runtime types before running full jobs"],"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"}