apache/iceberg · error · IllegalArgumentException

Unexpected object type for DATE logical type. Received:

Error message

Unexpected object type for DATE logical type. Received: 

What it means

convertToDate throws IllegalArgumentException when the object delivered for an Avro DATE logical type is neither java.time.LocalDate nor a Joda-convertible object (or Joda-Time is unavailable). The expected epoch-day conversion cannot be performed.

Source

Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/formats/avro/AvroToRowDataConverters.java:267

        return TimestampData.fromEpochMillis(jodaConverter.convertTimestamp(object));
      } else {
        throw new IllegalArgumentException(
            "Unexpected object type for TIMESTAMP logical type. Received: " + object);
      }
    }
  }

  private static int convertToDate(Object object) {
    if (object instanceof Integer) {
      return (Integer) object;
    } else if (object instanceof LocalDate) {
      return (int) ((LocalDate) object).toEpochDay();
    } else {
      JodaConverter jodaConverter = JodaConverter.getConverter();
      if (jodaConverter != null) {
        return (int) jodaConverter.convertDate(object);
      } else {
        throw new IllegalArgumentException(
            "Unexpected object type for DATE logical type. Received: " + object);
      }
    }
  }

  private static int convertToTime(Object object) {
    final int millis;
    if (object instanceof Integer) {
      millis = (Integer) object;
    } else if (object instanceof LocalTime) {
      millis = ((LocalTime) object).get(ChronoField.MILLI_OF_DAY);
    } else {
      JodaConverter jodaConverter = JodaConverter.getConverter();
      if (jodaConverter != null) {
        millis = jodaConverter.convertTime(object);
      } else {
        throw new IllegalArgumentException(
            "Unexpected object type for TIME logical type. Received: " + object);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Ensure the upstream Avro encoding decodes to java.time.LocalDate
  2. Add joda-time to the classpath if the producer wrote Joda date objects
  3. Convert the object to LocalDate/epochDay yourself before invoking the converter

Example fix

// before
int day = convertToDate(javaUtilDate); // throws
// after
int day = convertToDate(new LocalDate(javaUtilDate.getTime()).toEpochDay());
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(object instanceof LocalDate) && !isJodaDate(object)) { throw new IllegalArgumentException("Expected LocalDate for DATE field, got " + object.getClass()); }

Type guard

boolean isDateDatum(Object o) { return o instanceof LocalDate || o instanceof org.joda.time.LocalDate; }

Try / catch

try { return convertToDate(object); } catch (IllegalArgumentException e) { log.error("Bad DATE datum class: {}", object.getClass()); throw e; }

Prevention

When it happens

Trigger: Avro datum for a date field is a java.util.Date, Integer-epoch-days, ChronoLocalDate subclass, or other unexpected class; Joda converter absent for legacy Joda Date objects.

Common situations: Reading Avro files written by tools emitting non-java.time date representations; missing Joda-Time dependency when data uses Joda LocalDate.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/fde343bd2dbf31f6. Report an issue: GitHub.