apache/iceberg · error · IllegalArgumentException
Unsupported primitive type
Error message
Unsupported primitive type: <type>
What it means
Thrown by ParquetConversions.convertValue's outer default branch when the requested Iceberg primitive type has no Parquet-to-Iceberg value conversion implemented. The switch over the Iceberg type only handles known primitives; any other or unmapped type falls through to this error.
Solutions
- Use a supported Iceberg primitive type in the converter call.
- Upgrade Iceberg so the type is supported by ParquetConversions.
- Convert nested/complex values through the dedicated readers (value readers/struct readers) instead of convertValue.
Example fix
// before converter(parquetType, Types.NestedField.of(..., Types.StructType.get())) // after converter(parquetType, Types.IntegerType.get()) // or handle complex types with the standard readers
Defensive patterns
Strategy: type-guard
Validate before calling
if (icebergType.isPrimitiveType()) {
switch (icebergType.asPrimitiveType().typeId()) {
case BOOLEAN: case INT: case LONG: case FLOAT: case DOUBLE: case DATE: case TIME:
case TIMESTAMP: case STRING: case UUID: case FIXED: case BINARY: case DECIMAL: break;
default: throw new IllegalArgumentException("Type not convertible: " + icebergType);
}
} Type guard
boolean convertible(Type t) {
return t.isPrimitiveType();
} Try / catch
try {
Object v = ParquetConversions.convertValue(parquetType, type, scale, value);
} catch (IllegalArgumentException e) {
LOG.error("Unsupported type {} for Parquet conversion", type, e);
throw e;
} Prevention
- Only use convertValue/converterFromParquet for supported primitives.
- Keep Iceberg and writer versions aligned so new types have converter support.
- Route complex types through the generic value readers instead.
When it happens
Trigger: Passing an Iceberg type to convertValue that the converter does not support (e.g. a composite/nested type or a newer primitive added to the spec but not the converter), usually from converterFromParquet wiring.
Common situations: Custom read pipelines converting values manually; version skew where a new Iceberg type is read by an older converter; misuse of the public converter API with non-primitive types.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Avro writer does not support variant types
- Byte stream split encoding is not supported for type " +…
- Cannot convert unknown primitive type
- Cannot decode dictionary of type
- Not a boolean column
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/bfdf3bb7a7287eb3.
Report an issue: GitHub.
Appendix: source
Thrown at parquet/src/main/java/org/apache/iceberg/parquet/ParquetConversions.java:71
case FIXED:
case BINARY:
return (T) ((Binary) value).toByteBuffer();
case DECIMAL:
int scale =
((DecimalLogicalTypeAnnotation) parquetType.getLogicalTypeAnnotation()).getScale();
switch (parquetType.getPrimitiveTypeName()) {
case INT32:
case INT64:
return (T) BigDecimal.valueOf(((Number) value).longValue(), scale);
case FIXED_LEN_BYTE_ARRAY:
case BINARY:
return (T) new BigDecimal(new BigInteger(((Binary) value).getBytes()), scale);
default:
throw new IllegalArgumentException(
"Unsupported primitive type for decimal: " + parquetType.getPrimitiveTypeName());
}
default:
throw new IllegalArgumentException("Unsupported primitive type: " + type);
}
}
static Function<Object, Object> converterFromParquet(
PrimitiveType parquetType, Type icebergType) {
Function<Object, Object> fromParquet = converterFromParquet(parquetType);
if (icebergType != null) {
if (icebergType.typeId() == Type.TypeID.LONG
&& parquetType.getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.INT32) {
return value -> ((Integer) fromParquet.apply(value)).longValue();
} else if (icebergType.typeId() == Type.TypeID.DOUBLE
&& parquetType.getPrimitiveTypeName() == PrimitiveType.PrimitiveTypeName.FLOAT) {
return value -> ((Float) fromParquet.apply(value)).doubleValue();
} else if (icebergType.typeId() == Type.TypeID.UUID) {
return binary -> UUIDUtil.convert(((Binary) binary).toByteBuffer());
}
}
View on GitHub (pinned to 86d9c8fc54)