apache/iceberg · error · IllegalArgumentException

Unknown logical type: " + logicalType.getName()

Error message

Unknown logical type: " + logicalType.getName()

What it means

FlinkPlannedAvroReader's primitive builder maps Avro logical types (date, time-millis, timestamp-millis, decimal, uuid, ...) to Flink value readers; an unrecognized logical type name hits the default branch and throws IllegalArgumentException 'Unknown logical type: <name>'. Only logical types the reader explicitly knows are supported in this planned-read path.

Source

Thrown at flink/v2.2/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. Remove or change the unsupported logicalType in the Avro schema to a standard one (date, timestamp-millis, decimal, uuid)
  2. Read the column as its underlying primitive and convert in application code
  3. Upgrade Iceberg to a version that recognizes the logical type

Example fix

// before
{"type":"long","logicalType":"custom-duration"}
// after
{"type":"long"} // read as long, convert in code
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate the Avro schema's logical types
for (Schema.Field f : avroSchema.getFields()) {
  Schema s = f.schema();
  String lt = s.getLogicalType() != null ? s.getLogicalType().getName() : null;
  Preconditions.checkArgument(lt == null || KNOWN_LOGICAL_TYPES.contains(lt),
      "Unknown logical type: " + lt);
}

Try / catch

try {
  reader = readerBuilder.primitive(primitive, logicalType);
} catch (IllegalArgumentException e) {
  throw new AvroReadException("Cannot decode logical type: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Reading Avro data whose field has a logical type name not in the handled list (custom logicalType strings or logical types added after this Iceberg version), via FlinkPlannedAvroReader.primitive.

Common situations: Avro files written by external tools with custom or newer logical types, schema registry entries using vendor-specific logicalType values, or Avro format version changes.

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