apache/iceberg · error · UnsupportedOperationException
Unsupported type for Parquet
Error message
Unsupported type for Parquet: ${primitive} What it means
TypeToMessageType.primitive maps Iceberg primitive types to Parquet PrimitiveTypes with logical type annotations. The switch covers all known primitives; hitting default means an Iceberg primitive type has no Parquet mapping in this version, so conversion aborts with UnsupportedOperationException naming the type.
Solutions
- Read the type named in the message and confirm it is a supported Iceberg primitive for Parquet writes.
- Upgrade iceberg-parquet (and Iceberg generally) to a version that maps the type.
- Remove or remap the unsupported column (e.g. store as string/binary) if upgrading is not possible.
Example fix
// before Schema schema = new Schema(required(1, "v", Types.VariantType.get())); // older writer typeToMessageType.convert(schema.asStruct()); // after // upgrade to a version where VariantType maps to Parquet variant, or: Schema schema = new Schema(required(1, "v", Types.StringType.get()));
Defensive patterns
Strategy: validation
Validate before calling
Set<Class<?>> unsupported = schema.columns().stream()
.map(f -> f.type().getClass())
.filter(c -> !SUPPORTED_PARQUET_PRIMITIVES.contains(c))
.collect(Collectors.toSet());
if (!unsupported.isEmpty()) { throw new IllegalArgumentException("Unsupported for Parquet: " + unsupported); } Type guard
boolean supportedForParquet(Type t) { return t.isPrimitiveType() && KNOWN_MAPPINGS.containsKey(t.asPrimitiveType().typeId()); } Try / catch
try {
schemaDataType = typeToMessageType.convert(schema.asStruct());
} catch (UnsupportedOperationException e) {
LOG.error("Column type unsupported by this Iceberg version: {}", e.getMessage());
throw e;
} Prevention
- Align iceberg-core and iceberg-parquet versions before writing tables with new types.
- Validate schemas against supported Parquet types at job submission.
- Pre-remap unsupported columns (e.g. to string) when pinned to older versions.
When it happens
Trigger: Calling TypeToMessageType.primitive() (via field()) with an Iceberg primitive type not handled by the switch — typically a newly introduced type (e.g. a variant/geography/unknown-nanosecond type) on an older converter, or a custom primitive type.
Common situations: Writing tables whose schema uses a type added in a newer Iceberg spec while the parquet module is older; custom Type implementations; unknown types deserialized from foreign metadata.
Related errors
- Avro writer does not support variant types
- Byte stream split encoding is not supported for type " +…
- Can't convert unknown type
- Cannot convert unknown primitive type
- Cannot convert unknown type to Flink:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/7ee84a71f4223dc8.
Report an issue: GitHub.
Appendix: source
Thrown at parquet/src/main/java/org/apache/iceberg/parquet/TypeToMessageType.java:304
case GEOMETRY:
GeometryType geometry = (GeometryType) primitive;
return Types.primitive(BINARY, repetition)
.as(LogicalTypeAnnotation.geometryType(geometry.crs()))
.id(id)
.named(name);
case GEOGRAPHY:
GeographyType geography = (GeographyType) primitive;
return Types.primitive(BINARY, repetition)
.as(
LogicalTypeAnnotation.geographyType(
geography.crs(), toParquet(geography.algorithm())))
.id(id)
.named(name);
default:
throw new UnsupportedOperationException("Unsupported type for Parquet: " + primitive);
}
}
private static EdgeInterpolationAlgorithm toParquet(EdgeAlgorithm algorithm) {
// Iceberg and Parquet use the same algorithm names (SPHERICAL, VINCENTY, THOMAS, ANDOYER,
// KARNEY) so the algorithm is mapped by name
return EdgeInterpolationAlgorithm.valueOf(algorithm.name());
}
private static LogicalTypeAnnotation decimalAnnotation(int precision, int scale) {
return LogicalTypeAnnotation.decimalType(scale, precision);
}
}
View on GitHub (pinned to 86d9c8fc54)