apache/iceberg · error · IllegalArgumentException

Unsupported logical type: ${logicalType}

Error message

Unsupported logical type: ${logicalType}

What it means

FlinkAvroWriter converts Flink data to Avro values for Iceberg Avro file writing. Logical type mapping only handles a fixed set (string, date/time, timestamps, decimal, uuid); any other Avro logical type hits the default case and throws IllegalArgumentException 'Unsupported logical type'.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/data/FlinkAvroWriter.java:138

          case "time-micros":
            return FlinkValueWriters.timeMicros();

          case "timestamp-micros":
            return FlinkValueWriters.timestampMicros();

          case "timestamp-nanos":
            return FlinkValueWriters.timestampNanos();

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

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

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

      switch (primitive.getType()) {
        case NULL:
          return ValueWriters.nulls();
        case BOOLEAN:
          return ValueWriters.booleans();
        case INT:
          switch (type.getTypeRoot()) {
            case TINYINT:
              return ValueWriters.tinyints();
            case SMALLINT:
              return ValueWriters.shorts();
            default:
              return ValueWriters.ints();
          }
        case LONG:

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Remove or map the unsupported Avro logical type to a plain primitive in the writer schema
  2. Register support for the logical type by extending the writer switch (upstream change)
  3. Convert the column to a supported type before writing (e.g. store UUID as string if the logical type is not recognized)

Example fix

// before
Avro schema field with logicalType "custom-id" -> throws
// after
field.type() = string with no logicalType (or use the "uuid" logical type)
Defensive patterns

Strategy: validation

Validate before calling

LogicalType lt = field.schema().getLogicalType(); if (lt != null && !SUPPORTED_LOGICAL.contains(lt.getName())) throw new IllegalArgumentException("unsupported logical type " + lt);

Type guard

boolean supportedLogical(Schema s) { String n = s.getLogicalType() == null ? null : s.getLogicalType().getName(); return n == null || Set.of("string","date","time-millis","time-micros","timestamp-millis","timestamp-micros","decimal","uuid").contains(n); }

Try / catch

try { writer.write(row); } catch (IllegalArgumentException e) { LOG.error("Avro write failed: {}", e.getMessage()); throw e; }

Prevention

When it happens

Trigger: Writing Avro files for an Iceberg table whose Avro schema carries a logical type outside the supported set.

Common situations: Schemas produced by tools adding custom Avro logical types; hand-edited Avro schemas; ingesting foreign data with exotic logical types into an Iceberg Avro write path.

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