apache/iceberg · error · IllegalArgumentException
Unsupported logical type:
Error message
Unsupported logical type:
What it means
DataWriter maps Avro primitive schemas with logical types (decimal, uuid) to Iceberg ValueWriters; when it sees a logical type name it does not handle, this IllegalArgumentException is thrown listing nothing extra — just the logicalType string. Primitive types without logical types fall through to the normal switch below.
Source
Thrown at core/src/main/java/org/apache/iceberg/data/avro/DataWriter.java:141
return GenericWriters.timestamptz();
}
return GenericWriters.timestamps();
case "timestamp-nanos":
if (AvroSchemaUtil.isTimestamptz(primitive)) {
return GenericWriters.timestamptzNanos();
}
return GenericWriters.timestampNanos();
case "decimal":
LogicalTypes.Decimal decimal = (LogicalTypes.Decimal) logicalType;
return ValueWriters.decimal(decimal.getPrecision(), decimal.getScale());
case "uuid":
return ValueWriters.uuids();
default:
throw new IllegalArgumentException("Unsupported logical type: " + logicalType);
}
}
switch (primitive.getType()) {
case NULL:
return ValueWriters.nulls();
case BOOLEAN:
return ValueWriters.booleans();
case INT:
return ValueWriters.ints();
case LONG:
return ValueWriters.longs();
case FLOAT:
return ValueWriters.floats();
case DOUBLE:
return ValueWriters.doubles();
case STRING:
return ValueWriters.strings();View on GitHub (pinned to 86d9c8fc54)
Solutions
- Convert the field to a supported type (decimal or uuid) before writing
- Handle unsupported logical types upstream by stripping the logical type or converting values to an Iceberg-supported primitive
- Extend the writer with a mapping if the logical type maps naturally to an Iceberg type (e.g. timestamp)
Example fix
// before
// schema: {"type":"int","logicalType":"time-millis"} passed to DataWriter
// after
// convert value to the target Iceberg type first, e.g. TimeType written via TimeMicrosWriter
long micros = TimeUnit.MILLISECONDS.toMicros(millisOfDay); Defensive patterns
Strategy: validation
Validate before calling
LogicalType lt = schema.getLogicalType();
String name = lt != null ? lt.getName() : null;
if (name != null && !"decimal".equals(name) && !"uuid".equals(name)) throw new IllegalStateException("unsupported logical type: " + name); Type guard
boolean supportedLogicalType(Schema s) { Object lt = s.getLogicalType(); return lt == null || lt instanceof LogicalTypes.Decimal || "uuid".equals(lt.getName()); } Try / catch
try { DataWriter.write(encoder, schema, value); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unsupported logical type")) { /* convert upstream */ } else throw e; } Prevention
- Convert foreign Avro logical types before writing through the generic writer
- Restrict input schemas to decimal/uuid logical types
- Document accepted schema shapes for ingestion pipelines
When it happens
Trigger: Writing Avro data with a primitive schema carrying a logical type other than decimal or uuid (e.g. time-millis, timestamp-micros, or a custom logical type).
Common situations: Foreign Avro files with timestamp/timedelta logical types being written through the Iceberg generic writer; custom Avro logical types from other systems.
Related errors
- Cannot write null to required string column
- Cannot write unknown string type:
- Unknown logical type:
- Unknown logical type: ${logicalType.getName()}
- Unsupported type: ${type}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/6aae020e85525b71.
Report an issue: GitHub.