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

  1. Inspect the Avro schema (printSchema / avro tools) to see which logical type is declared
  2. Rewrite the data removing the unsupported logical annotation (treat the field as its underlying primitive)
  3. Cast or re-map the column in the Iceberg table schema to a supported type
  4. 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

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/42146d1f4b5af78f. Report an issue: GitHub.