apache/iceberg · error · IllegalArgumentException
Unexpected object type for DATE logical type. Received: " +
Error message
Unexpected object type for DATE logical type. Received: " + object
What it means
convertToDate converts the Avro-decoded object for a DATE logical type into epoch-day int. It supports java.time.LocalDate and Joda-readable objects (when JodaConverter is available); anything else raises IllegalArgumentException("Unexpected object type for DATE logical type. Received: " + object). It fires when the runtime object doesn't match the declared DATE logical type.
Source
Thrown at flink/v2.2/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
- Ensure the producer's Avro schema applies the 'date' logical type so the decoder yields LocalDate.
- Add joda-time to the classpath if consuming legacy Joda-encoded data.
- Check the printed object type in the message and align the Flink column type (e.g. INT for raw day counts).
Example fix
// before
{ "name": "d", "type": "int" } // no logicalType
// after
{ "name": "d", "type": { "type": "int", "logicalType": "date" } } Defensive patterns
Strategy: type-guard
Validate before calling
if (!(avroObject instanceof LocalDate) && JodaConverter.getConverter() == null) { throw new IllegalStateException("DATE field decodes to " + avroObject.getClass() + " and Joda converter unavailable"); } Type guard
boolean isSupportedDateObject(Object o) { return o instanceof LocalDate || (isJodaDate(o) && JodaConverter.getConverter() != null); } Try / catch
try { int day = convertToDate(avroObject); } catch (IllegalArgumentException e) { /* log object class, fix schema or converter */ } Prevention
- Ensure producer schemas apply the Avro 'date' logicalType.
- Never assume plain ints carry date semantics; declare types explicitly.
- Validate decoded object classes in a smoke test job.
When it happens
Trigger: An Avro field with date logical type decodes to an unexpected object (e.g. Integer millis because the schema declared int without the date logical type, or a String date), or Joda converter is unavailable for legacy Joda-encoded dates.
Common situations: Avro schema/actual data mismatch: producer writes plain int but consumer schema declares Avro 'date'; missing joda-time dependency; custom decoders bypassing logical-type conversion.
Related errors
- Unexpected object type for DATE logical type. Received: ${ob
- Unexpected object type for DATE logical type. Received: ${ob
- Unexpected object type for DATE logical type. Received:
- Unexpected object type for TIMESTAMP logical type. Received:
- Unexpected object type for TIME logical type. Received: ${ob
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/9d7e4ca7d535e97b.
Report an issue: GitHub.