apache/iceberg · error · IllegalArgumentException
Unknown logical type:
Error message
Unknown logical type:
What it means
SparkPlannedAvroReader.primitive() maps Avro logical types (LogicalType) to Spark value readers. When an Avro schema carries a logical type name that is not one of the supported ones (e.g. not decimal or uuid in this branch), it throws IllegalArgumentException("Unknown logical type: ..."). Reading files containing such a schema fails at reader construction.
Source
Thrown at spark/v4.0/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
- Inspect the Avro schema (printSchema / avro tools) to see which logical type is declared
- Rewrite the data removing the unsupported logical annotation (treat the field as its underlying primitive)
- Cast or re-map the column in the Iceberg table schema to a supported type
- Upgrade Iceberg if the logical type is supported in newer releases
Defensive patterns
Strategy: validation
Validate before calling
Schema avroSchema = datumReader.getSchema();
for (Field f : avroSchema.getFields()) {
LogicalType lt = f.schema().getLogicalType();
if (lt != null && !Set.of("decimal", "uuid").contains(lt.getName())) {
throw new IllegalStateException("Unsupported Avro logical type in field " + f.name() + ": " + lt);
}
} Type guard
boolean hasSupportedLogicalType(Schema s) {
LogicalType lt = s.getLogicalType();
return lt == null || "decimal".equals(lt.getName()) || "uuid".equals(lt.getName());
} Try / catch
try {
spark.read().format("iceberg").load("db.tbl");
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unknown logical type")) {
// strip or rewrite the unsupported logical annotation, then retry
} else {
throw e;
}
} Prevention
- Inspect Avro schemas from external producers (Kafka Connect, registries) before ingesting into Iceberg tables
- Strip unsupported logical annotations and treat fields as their underlying primitive types
- Keep the Iceberg version of the reader at least as new as the writer's logical-type usage
When it happens
Trigger: Reading an Avro-backed Iceberg data file whose field schema declares a logical type other than the handled names (e.g. 'time-micros', 'timestamp-millis', or custom logical types) while planning a Spark scan.
Common situations: Avro files produced by other systems (Kafka Connect, custom pipelines) with logical annotations Iceberg's Avro reader does not map; schema registry injecting logical types; version skew between producer and reader Iceberg versions.
Related errors
- Unknown logical type: ${logicalType}
- Unknown logical type: ${logicalType}
- 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/42146d1f4b5af78f.
Report an issue: GitHub.