apache/iceberg · error · IllegalArgumentException

Unknown logical type:

Error message

Unknown logical type: 

What it means

PlannedDataReader.primitive() maps Avro primitive types (including logical types like date, timestamp-micros, decimal, uuid) to Iceberg ValueReaders. When a logical type name isn't among the recognized ones, it throws this IllegalArgumentException. The read schema contains a logical type the reader can't map.

Source

Thrown at core/src/main/java/org/apache/iceberg/data/avro/PlannedDataReader.java:172

            }
            return GenericReaders.timestampNanos();

          case "timestamp-millis":
            if (AvroSchemaUtil.isTimestamptz(primitive)) {
              return GenericReaders.timestamptzMillis();
            }
            return GenericReaders.timestampMillis();

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

          case "uuid":
            return ValueReaders.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. Identify the unknown logical type from the message and remove or convert it in the write schema.
  2. Upgrade Iceberg to a version recognizing that logical type.
  3. Register/handle the logical type before reading, or map the field to a supported primitive.
  4. If support is missing in Iceberg, add a case for the logical type name in PlannedDataReader.

Example fix

// before
Schema field = LogicalTypes.duration().addToSchema(Schema.create(Schema.Type.FIXED));
reader.read(schema, decoder); // Unknown logical type: duration
// after
Schema field = LogicalTypes.timestampMicros().addToSchema(Schema.create(Schema.Type.LONG));
reader.read(schema, decoder);
Defensive patterns

Strategy: validation

Validate before calling

for (Schema.Field f : schema.getFields()) {
  LogicalType lt = f.schema().getLogicalType();
  if (lt != null && !Set.of("date","time-millis","time-micros","timestamp-millis","timestamp-micros","decimal","uuid").contains(lt.getName())) {
    throw new IllegalArgumentException("Unsupported logical type: " + lt.getName());
  }
}

Type guard

null

Try / catch

try { return reader.read(schema, decoder); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unknown logical type")) { return readWithConvertedSchema(convertLogicalTypes(schema), decoder); } throw e; }

Prevention

When it happens

Trigger: Reading Avro data whose schema contains a logical type other than date/time-millis/time-micros/timestamp-millis/timestamp-micros/decimal/uuid (e.g. local-timestamp-micros, duration) via PlannedDataReader.

Common situations: Data written by Avro libraries using newer or exotic logical types; schema evolution adding logical types after the reader was written; Avro version differences introducing new logical type names.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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