apache/iceberg · error · IllegalArgumentException
Unknown logical type:
Error message
Unknown logical type:
What it means
PlannedDataReader.primitive() maps Avro primitive types (including logical types like date, timestamp-micros, decimal, uuid) to Iceberg ValueReaders. When a logical type name isn't among the recognized ones, it throws this IllegalArgumentException. The read schema contains a logical type the reader can't map.
Source
Thrown at core/src/main/java/org/apache/iceberg/data/avro/PlannedDataReader.java:172
}
return GenericReaders.timestampNanos();
case "timestamp-millis":
if (AvroSchemaUtil.isTimestamptz(primitive)) {
return GenericReaders.timestamptzMillis();
}
return GenericReaders.timestampMillis();
case "decimal":
return ValueReaders.decimal(
ValueReaders.decimalBytesReader(primitive),
((LogicalTypes.Decimal) logicalType).getScale());
case "uuid":
return ValueReaders.uuids();
default:
throw new IllegalArgumentException("Unknown logical type: " + logicalType);
}
}
switch (primitive.getType()) {
case NULL:
return ValueReaders.nulls();
case BOOLEAN:
return ValueReaders.booleans();
case INT:
if (partner != null && partner.typeId() == Type.TypeID.LONG) {
return ValueReaders.intsAsLongs();
}
return ValueReaders.ints();
case LONG:
return ValueReaders.longs();
case FLOAT:
if (partner != null && partner.typeId() == Type.TypeID.DOUBLE) {
return ValueReaders.floatsAsDoubles();View on GitHub (pinned to 86d9c8fc54)
Solutions
- Identify the unknown logical type from the message and remove or convert it in the write schema.
- Upgrade Iceberg to a version recognizing that logical type.
- Register/handle the logical type before reading, or map the field to a supported primitive.
- If support is missing in Iceberg, add a case for the logical type name in PlannedDataReader.
Example fix
// before Schema field = LogicalTypes.duration().addToSchema(Schema.create(Schema.Type.FIXED)); reader.read(schema, decoder); // Unknown logical type: duration // after Schema field = LogicalTypes.timestampMicros().addToSchema(Schema.create(Schema.Type.LONG)); reader.read(schema, decoder);
Defensive patterns
Strategy: validation
Validate before calling
for (Schema.Field f : schema.getFields()) {
LogicalType lt = f.schema().getLogicalType();
if (lt != null && !Set.of("date","time-millis","time-micros","timestamp-millis","timestamp-micros","decimal","uuid").contains(lt.getName())) {
throw new IllegalArgumentException("Unsupported logical type: " + lt.getName());
}
} Type guard
null
Try / catch
try { return reader.read(schema, decoder); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unknown logical type")) { return readWithConvertedSchema(convertLogicalTypes(schema), decoder); } throw e; } Prevention
- Restrict write-side schemas to logical types the reader knows
- Align Avro library versions between producer and consumer
- Convert exotic logical types (duration, local-timestamp) before writing
When it happens
Trigger: Reading Avro data whose schema contains a logical type other than date/time-millis/time-micros/timestamp-millis/timestamp-micros/decimal/uuid (e.g. local-timestamp-micros, duration) via PlannedDataReader.
Common situations: Data written by Avro libraries using newer or exotic logical types; schema evolution adding logical types after the reader was written; Avro version differences introducing new logical type names.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unsupported type:
- Unknown logical type: ${logicalType.getName()}
- Unknown logical type:
- Unsupported type:
- Unsupported logical type: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4d6fbe8b636cc9f2.
Report an issue: GitHub.