apache/iceberg · error · IllegalArgumentException

Unknown logical type: ${logicalType.getName()}

Error message

Unknown logical type: ${logicalType.getName()}

What it means

FlinkPlannedAvroReader.primitive() maps Avro primitives to Flink value readers. When an Avro string/bytes primitive carries a logical type name (via a logicalType conversion), only a fixed set (e.g. decimal, uuid) is recognized; other names throw IllegalArgumentException 'Unknown logical type'.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/data/FlinkPlannedAvroReader.java:160

          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 from the message and remove or convert it in the producer schema to a supported type.
  2. Upgrade Iceberg to a version where FlinkPlannedAvroReader handles that logical type.
  3. Cast the column to a plain string/bytes upstream so it no longer carries the unrecognized logical type.
  4. Register a custom conversion or patch the reader switch if the logical type is business-required.

Example fix

// before: Avro field {"type":"bytes","logicalType":"custom-thing"}
// after: producer writes {"type":"bytes"} (no logicalType) or converts to supported decimal/uuid
Defensive patterns

Strategy: validation

Validate before calling

Schema avroSchema = ...;
for (Field f : avroSchema.getFields()) {
  LogicalType lt = AvroSchemaUtil.convert(f.schema()).getLogicalType();
  if (lt != null && !Set.of("decimal", "uuid").contains(lt.getName())) {
    throw new IllegalArgumentException("unsupported avro logical type: " + lt.getName());
  }
}

Try / catch

try {
  reader = FlinkPlannedAvroReader.create(readSchema, predicate);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Unknown logical type:")) {
    // rebuild read schema without the unsupported logical type
  }
}

Prevention

When it happens

Trigger: Reading an Avro-backed Parquet/Avro source whose primitive has a logical type the reader's switch does not cover (anything besides the handled decimal/uuid names in that branch).

Common situations: Avro files produced with custom or newer logical types (e.g. time-micros variants in some branches, or vendor-specific names); Iceberg version that predates support for a standard logical type; schema drift between producer and consumer.

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/cad135d66568906e. Report an issue: GitHub.