apache/iceberg · error · IllegalArgumentException
Unhandled type
Error message
Unhandled type
What it means
ORCSchemaUtil.convert maps Iceberg Types to ORC TypeDescriptions. The switch over type.typeId() has no ORC equivalent branch for every Iceberg type (e.g. unknown/future or non-primitive nested typeIds reach the default arm), so an IllegalArgumentException naming the typeId is thrown. Callers convert(...) recurse through childType/elementType/keyType/valueType and buildOrcProjection, so the error surfaces while building the ORC schema or projection.
Source
Thrown at orc/src/main/java/org/apache/iceberg/orc/ORCSchemaUtil.java:261
case MAP:
{
Types.MapType map = (Types.MapType) type;
// Only the value can be set as an unknown by definition:
// UnknownType requires to be optional, and the key has to be required.
Preconditions.checkArgument(
map.valueType().typeId() != Type.TypeID.UNKNOWN,
"Cannot create MapType with unknown value type");
TypeDescription keyType = convert(map.keyId(), map.keyType(), true);
TypeDescription valueType =
convert(map.valueId(), map.valueType(), map.isValueRequired());
orcType = TypeDescription.createMap(keyType, valueType);
break;
}
default:
throw new IllegalArgumentException("Unhandled type " + type.typeId());
}
// Set Iceberg column attributes for mapping
orcType.setAttribute(ICEBERG_ID_ATTRIBUTE, String.valueOf(fieldId));
orcType.setAttribute(ICEBERG_REQUIRED_ATTRIBUTE, String.valueOf(isRequired));
return orcType;
}
/**
* Convert an ORC schema to an Iceberg schema. This method handles the conversion from the
* original Iceberg column mapping IDs if present in the ORC column attributes, otherwise, ORC
* columns with no Iceberg IDs will be ignored and skipped in the conversion.
*
* @return the Iceberg schema
* @throws IllegalArgumentException if ORC schema has no columns with Iceberg ID attributes
*/
public static Schema convert(TypeDescription orcSchema) {
List<TypeDescription> children = orcSchema.getChildren();View on GitHub (pinned to 86d9c8fc54)
Solutions
- Inspect the typeId in the message and rewrite the schema so it only uses ORC-supported Iceberg types (primitive types, struct, list, map).
- Upgrade the Iceberg ORC module so the conversion switch covers the type you use.
- If the type is genuinely unmappable, change the table schema or fall back to a different file format (Parquet/Avro) that supports it.
Example fix
// before
Schema schema = new Schema(
Types.NestedField.required(1, "u", Types.UnknownType.get())); // unsupported in ORC
TypeDescription orc = ORCSchemaUtil.convert(schema);
// after
Schema schema = new Schema(
Types.NestedField.required(1, "s", Types.StringType.get())); // mapped type
TypeDescription orc = ORCSchemaUtil.convert(schema); Defensive patterns
Strategy: validation
Validate before calling
for (Types.NestedField f : schema.columns()) {
switch (f.type().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: case STRUCT: case LIST: case MAP:
break;
default:
throw new IllegalArgumentException("Type not ORC-mappable: " + f.type());
}
} Try / catch
try {
TypeDescription orc = ORCSchemaUtil.convert(schema);
} catch (IllegalArgumentException e) {
LOG.error("Unmappable Iceberg type for ORC: {}", e.getMessage());
throw e;
} Prevention
- Keep table schemas within ORC-supported Iceberg types
- Validate schemas before creating ORC tables in mixed-engine environments
- Upgrade the ORC module when using newly added Iceberg types
When it happens
Trigger: Calling ORCSchemaUtil.convert(schema/spec projection) when the Iceberg schema contains a type whose typeId has no case in the conversion switch (e.g. newer Iceberg types added after the ORC mapping was written, or a nested schema element that reaches the default arm).
Common situations: Writing ORC files for a table with a type added in a newer Iceberg spec than the ORC mapping supports; version mismatch between Iceberg versions when a schema was created elsewhere (Spark/Flink) with types not mapped in ORC; feeding a synthetic/unknown Type to the converter.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- ORC schema does not contain Iceberg IDs
- Field + name + not found in source schema
- Cannot parse type string to primitive: + typeString
- Invalid default value for %s: %s (must be null)
- Cannot parse default as a %s value: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/7062b85452728377.
Report an issue: GitHub.