apache/iceberg · error · IllegalArgumentException

Unsupported logical type:

Error message

Unsupported logical type: 

What it means

SparkAvroWriter.primitive maps Avro logical types to Iceberg value writers. Only date, timestamp-millis/micros, decimal, and uuid logical types are recognized; anything else hits the default branch. This IllegalArgumentException reports that the Avro schema contains a logical type the Spark-to-Iceberg writer cannot handle.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/data/SparkAvroWriter.java:137

      if (logicalType != null) {
        switch (logicalType.getName()) {
          case "date":
            // Spark uses the same representation
            return ValueWriters.ints();

          case "timestamp-micros":
            // Spark uses the same representation
            return ValueWriters.longs();

          case "decimal":
            LogicalTypes.Decimal decimal = (LogicalTypes.Decimal) logicalType;
            return SparkValueWriters.decimal(decimal.getPrecision(), decimal.getScale());

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

          default:
            throw new IllegalArgumentException("Unsupported logical type: " + logicalType);
        }
      }

      switch (primitive.getType()) {
        case NULL:
          return ValueWriters.nulls();
        case BOOLEAN:
          return ValueWriters.booleans();
        case INT:
          if (type instanceof ByteType) {
            return ValueWriters.tinyints();
          } else if (type instanceof ShortType) {
            return ValueWriters.shorts();
          }
          return ValueWriters.ints();
        case LONG:
          return ValueWriters.longs();
        case FLOAT:

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Remove or normalize the unsupported logical type from the Avro schema (write as underlying primitive).
  2. Convert time-millis/time-micros fields to timestamp-micros or plain int/long before writing.
  3. Upgrade Iceberg if a newer release supports the logical type.
  4. If writing via a different library, use a writer that supports the logical type.

Example fix

// before (Avro schema)
{"name":"t","type":"int","logicalType":"time-millis"}
// after
{"name":"t","type":"long","logicalType":"timestamp-micros"}
Defensive patterns

Strategy: validation

Validate before calling

// Inspect the Avro schema's logical types before writing
for (org.apache.avro.Schema.Field f : avroSchema.getFields()) {
  org.apache.avro.LogicalType lt = f.schema().getLogicalType();
  if (lt != null && !Set.of("date", "timestamp-millis", "timestamp-micros", "decimal", "uuid").contains(lt.getName())) {
    throw new IllegalStateException("Unsupported logical type: " + lt.getName());
  }
}

Type guard

static boolean isSupportedLogicalType(org.apache.avro.Schema s) {
  org.apache.avro.LogicalType lt = s.getLogicalType();
  return lt == null || Set.of("date", "timestamp-millis", "timestamp-micros", "decimal", "uuid").contains(lt.getName());
}

Prevention

When it happens

Trigger: Writing Spark InternalRows to an Avro container whose schema declares a logical type other than date, timestamp-millis, timestamp-micros, decimal, or uuid (e.g. time-millis, time-micros, duration, or a custom logicalType).

Common situations: Third-party tools emit Avro schemas with time-millis/time-micros or vendor-specific logical types; attempts to write such data through Iceberg's SparkAvroWriter path fail.

Related errors


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