apache/iceberg · error · IllegalArgumentException
Unexpected object type for TIME logical type. Received: ${ob
Error message
Unexpected object type for TIME logical type. Received: ${object} What it means
convertToTime converts an Avro TIME logical-type value into millis-of-day for Flink TIME. Expected inputs are LocalTime or Joda-handled types; anything else (with no Joda converter available) triggers this IllegalArgumentException identifying the actual object.
Source
Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/formats/avro/AvroToRowDataConverters.java:284
} 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);
}
}
return millis;
}
private static byte[] convertToBytes(Object object) {
if (object instanceof GenericFixed) {
return ((GenericFixed) object).bytes();
} else if (object instanceof ByteBuffer) {
ByteBuffer byteBuffer = (ByteBuffer) object;
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
return bytes;
} else {
return (byte[]) object;
}
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Align the table's time-unit mapping property with the actual file encoding and rewrite files if necessary.
- Add the joda-time dependency when reading legacy Joda-encoded TIME values.
- Check the 'Received:' class in the message and pre-convert that value (e.g. Long millis → LocalTime) before conversion.
Example fix
// before
Object v = record.get("t"); // Long millis
RowData row = converter.convert(record); // throws
// after
record.put("t", LocalTime.ofNanoOfDay((Long) v * 1_000_000));
RowData row = converter.convert(record); Defensive patterns
Strategy: validation
Validate before calling
Object v = record.get("t");
if (!(v instanceof LocalTime) && !jodaSupported(v)) { throw new IllegalArgumentException("t has unexpected class: " + v.getClass()); } Type guard
boolean isSupportedTime(Object v) { return v instanceof LocalTime || v instanceof org.joda.time.LocalTime; } Try / catch
try { return convertToTime(obj); } catch (IllegalArgumentException e) { return (int) toLocalTime(obj).get(ChronoField.MILLI_OF_DAY); } Prevention
- Align time-unit mapping properties with actual file encoding
- Ensure joda-time dependency is present for legacy encodings
- Check the 'Received:' class in the message to identify mapping mismatches quickly
When it happens
Trigger: Avro TIME field decoded as a class other than LocalTime (e.g. Long micros/millis) while legacyTimestampMapping expectations differ, or joda-time missing so JodaConverter is null for legacy Joda-encoded times.
Common situations: Files written with legacy time-unit encoding read by a converter expecting modern types; missing joda-time dependency; schema property mapping changed without data rewrite.
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
- Unexpected object type for TIME logical type. Received: ${ob
- Unexpected object type for TIME logical type. Received: " +
- Unexpected object type for TIME logical type. Received:
- Unexpected object type for TIMESTAMP logical type. Received:
- Unexpected object type for DATE logical type. Received: ${ob
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/bdda4c9258a59155.
Report an issue: GitHub.