apache/iceberg · error · IllegalArgumentException
Unknown logical type: ${logicalType}
Error message
Unknown logical type: ${logicalType} What it means
SparkPlannedAvroReader maps Avro logical types (date, timestamp-millis, decimal, uuid, etc.) to value readers. An Avro logical type name outside the recognized set triggers IllegalArgumentException('Unknown logical type: ...').
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/data/SparkPlannedAvroReader.java:162
case "timestamp-millis":
// adjust to microseconds
ValueReader<Long> longs = ValueReaders.longs();
return (ValueReader<Long>) (decoder, ignored) -> longs.read(decoder, null) * 1000L;
case "timestamp-micros":
// Spark uses the same representation
return ValueReaders.longs();
case "decimal":
return SparkValueReaders.decimal(
ValueReaders.decimalBytesReader(primitive),
((LogicalTypes.Decimal) logicalType).getScale());
case "uuid":
return SparkValueReaders.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
- Upgrade Iceberg so the reader recognizes the logical type.
- Remove or convert the custom logical-typed field before writing files.
- Strip or change the logical type annotation in the producing Avro schema.
Example fix
// before
{"name":"f","type":"long","logicalType":"custom-thing"}
// after
{"name":"f","type":"long"} Defensive patterns
Strategy: validation
Validate before calling
Schema avroSchema = new Schema.Parser().parse(schemaJson);
for (Field f : avroSchema.getFields()) {
LogicalType lt = f.schema().getLogicalType();
if (lt != null && !Set.of("date","timestamp-millis","timestamp-micros","decimal","uuid","time-millis","time-micros").contains(lt.getName()))
throw new IllegalStateException("unknown logical type: " + lt.getName());
} Try / catch
try {
reader = SparkPlannedAvroReader.create(avroSchema);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unknown logical type")) {
// strip/convert the custom logical type and retry
}
} Prevention
- Stick to standard Avro logical types when producing files.
- Upgrade Iceberg before reading files from newer producers.
When it happens
Trigger: Reading an Avro-backed Iceberg file whose schema declares a logical type the reader doesn't know (custom or newer logical type names).
Common situations: Avro files produced by external tools with custom logical types; reading files written by newer Iceberg/Avro versions with logical types unknown to the runtime's reader.
Related errors
- Unknown logical type: ${logicalType}
- Unknown logical type:
- Unknown logical type:
- Unknown logical type: ${logicalType.getName()}
- Unknown logical type:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ff3112bd88a26a23.
Report an issue: GitHub.