apache/iceberg · error · IllegalArgumentException

Unsupported logical type:

Error message

Unsupported logical type: 

What it means

SparkAvroWriter.primitive maps Spark types to Avro value writers. For a BYTES primitive with a logical type it recognizes decimal and uuid only; any other Avro logical type name hits the default branch and throws IllegalArgumentException('Unsupported logical type: ...').

Source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/data/SparkAvroWriter.java:142

      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. Upgrade the Iceberg runtime to a version supporting the logical type
  2. Remove or change the unsupported logical type in the Avro schema (e.g. use plain bytes)
  3. Convert the data to a supported type before writing (e.g. UUID strings, decimal)
  4. If the type should be supported, file an issue with the logical type name

Example fix

// before
Schema.Field f = new Schema.Field("id", LogicalTypes.unknown().addToSchema(Schema.create(Schema.Type.BYTES)));
// after: use a supported logical type or plain bytes
Schema.Field f = new Schema.Field("id", Schema.create(Schema.Type.BYTES));
Defensive patterns

Strategy: validation

Validate before calling

for (Schema.Field f : avroSchema.getFields()) {
  LogicalType lt = f.schema().getLogicalType();
  if (lt != null && !"decimal".equals(lt.getName()) && !"uuid".equals(lt.getName())) {
    throw new IllegalArgumentException("Unsupported logical type: " + lt);
  }
}

Type guard

boolean supported(Schema s) { LogicalType lt = s.getLogicalType(); return lt == null || lt instanceof LogicalTypes.Decimal || "uuid".equals(lt.getName()); }

Try / catch

try { writer.write(row); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unsupported logical type")) { /* fix schema */ } else { throw e; } }

Prevention

When it happens

Trigger: Writing Spark data through SparkAvroWriter when the Avro schema declares a BYTES/FIXED primitive with a logical type the writer doesn't support (anything besides decimal and uuid).

Common situations: Custom or vendor-specific Avro logical types in the schema; newer logical types written by other tools being read/written by an older Iceberg runtime; schema evolution introducing logical types the writer predates.

Related errors


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