apache/iceberg · error · java.lang.IllegalArgumentException

Unknown logical type:

Error message

Unknown logical type: 

What it means

In FlinkPlannedAvroReader's ReadBuilder.primitive(...), Avro logical types (logicalType.getName()) are matched by name: decimal, date, time-micros, timestamp-micros, uuid etc. produce dedicated Flink readers; any other logical type name hits the default branch and throws IllegalArgumentException 'Unknown logical type'.

Source

Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/data/FlinkPlannedAvroReader.java:166

          case "timestamp-micros":
            return FlinkValueReaders.timestampMicros();

          case "timestamp-nanos":
            return FlinkValueReaders.timestampNanos();

          case "decimal":
            LogicalTypes.Decimal decimal = (LogicalTypes.Decimal) logicalType;
            return FlinkValueReaders.decimal(
                ValueReaders.decimalBytesReader(primitive),
                decimal.getPrecision(),
                decimal.getScale());

          case "uuid":
            return FlinkValueReaders.uuids();

          default:
            throw new IllegalArgumentException("Unknown logical type: " + logicalType.getName());
        }
      }

      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. Identify the logical type name in the error and the Avro schema; check whether the producing library version supports it and align versions.
  2. Rewrite the data without the unsupported logical type (plain primitive) or with a supported one (decimal/date/timestamp-micros/uuid).
  3. Add a case for the logical type in the switch returning an appropriate reader, and upstream it.

Example fix

// before: Avro field with logicalType "time-millis"
// after: rewrite as "time-micros" or plain int with manual conversion
Defensive patterns

Strategy: validation

Validate before calling

// java
Set<String> known = Set.of("decimal", "date", "time-micros", "timestamp-micros", "uuid");
Object logical = schema.getLogicalType(null);
if (logical != null && !known.contains(((org.apache.avro.LogicalType) logical).getName())) {
  throw new IllegalArgumentException("Unsupported Avro logical type");
}

Try / catch

// java
try {
  FlinkAvroReaderFactory/reader = FlinkPlannedAvroReader.create(schema);
} catch (IllegalArgumentException e) {
  // handle unknown logical type: rewrite data or upgrade runtime
}

Prevention

When it happens

Trigger: Reading Avro data whose schema declares a logical type name that FlinkPlannedAvroReader does not recognize (e.g. time-millis, local-timestamp-micros, duration, or custom logical types), while planning a reader for the Avro primitive schema.

Common situations: Avro files written by newer Iceberg versions supporting logical types this reader doesn't know; third-party producers emitting custom logical type names; version skew where the reader is older than the data producer.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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