apache/iceberg · error · IllegalArgumentException

Unsupported logical type:

Error message

Unsupported logical type: 

What it means

FlinkAvroWriter's visitor throws IllegalArgumentException('Unsupported logical type: ...') when an Avro primitive carries a logical type (e.g. a date/time/decimal-like logicalType string) that the writer has no value writer for.

Source

Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/data/FlinkAvroWriter.java:144

          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. Change the Avro schema to use a supported logical type (decimal, date, timestamp-millis, uuid) or drop the logicalType attribute.
  2. Add/customize the writer to handle the logical type via FlinkValueWriters.
  3. Normalize the schema before writing (e.g. map unknown logical types to plain primitives).

Example fix

// before
{"name":"f","type":"long","logicalType":"time-micros"} // unsupported
// after
{"name":"f","type":"int","logicalType":"date"} // supported logical type
Defensive patterns

Strategy: validation

Validate before calling

Set<String> supported = Set.of("decimal","date","timestamp-millis","uuid");
schema.fields().forEach(f -> {
  Object lt = f.logicalType();
  if (lt != null && !supported.contains(lt.toString())) throw new IllegalStateException("Unsupported logical type: " + lt);
});

Type guard

boolean hasSupportedLogicalType(Schema.Field f) { return f.logicalType() == null || SUPPORTED_LOGICALS.contains(f.logicalType().toString()); }

Try / catch

try { writer.write(rowData); } catch (IllegalArgumentException e) { /* regenerate Avro schema with supported logical types */ }

Prevention

When it happens

Trigger: Writing Flink RowData to Avro where the target Avro field's logicalType attribute is not one of the handled values (date/timestamp-millis/decimal/uuid handled; others hit default).

Common situations: Custom Avro schemas with nonstandard logicalType names; Avro schemas produced by other systems using logical types this connector doesn't recognize; schema registry supplied schemas.

Related errors


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