apache/iceberg · error
Cannot parse type string: variant is not a primitive type
Error message
Cannot parse type string: variant is not a primitive type
What it means
Thrown by Types.fromPrimitiveString when fromTypeName successfully parsed the string but the result is a nested (non-primitive) type. fromPrimitiveString only accepts primitive types; note the hardcoded message mentions 'variant' because VariantType is the notable nested type reachable via a plain name lookup.
Source
Thrown at api/src/main/java/org/apache/iceberg/types/Types.java:115
if (fixed.matches()) {
return FixedType.ofLength(Integer.parseInt(fixed.group(1)));
}
Matcher decimal = DECIMAL.matcher(lowerTypeString);
if (decimal.matches()) {
return DecimalType.of(Integer.parseInt(decimal.group(1)), Integer.parseInt(decimal.group(2)));
}
throw new IllegalArgumentException("Cannot parse type string to primitive: " + typeString);
}
public static PrimitiveType fromPrimitiveString(String typeString) {
Type type = fromTypeName(typeString);
if (type.isPrimitiveType()) {
return type.asPrimitiveType();
}
throw new IllegalArgumentException("Cannot parse type string: variant is not a primitive type");
}
public static class BooleanType extends PrimitiveType {
private static final BooleanType INSTANCE = new BooleanType();
public static BooleanType get() {
return INSTANCE;
}
@Override
public TypeID typeId() {
return TypeID.BOOLEAN;
}
@Override
public String toString() {
return "boolean";
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use Types.fromTypeName instead if nested types are acceptable
- Verify the column's type is primitive before requesting a PrimitiveType (check typeID, e.g. VariantType.typeId() == Variant)
- Handle variant columns separately from primitive columns in your logic
Example fix
// before
PrimitiveType p = Types.fromPrimitiveString("variant");
// after
Type t = Types.fromTypeName("variant");
if (t.isPrimitiveType()) {
PrimitiveType p = t.asPrimitiveType();
} Defensive patterns
Strategy: type-guard
Validate before calling
Type t = Types.fromTypeName(typeString);
if (!t.isPrimitiveType()) { throw new IllegalArgumentException("Expected primitive type, got: " + t); } Type guard
PrimitiveType asPrimitiveOrNull(String typeString) {
Type t = Types.fromTypeName(typeString);
return t.isPrimitiveType() ? t.asPrimitiveType() : null;
} Try / catch
try {
PrimitiveType p = Types.fromPrimitiveString(typeString);
} catch (IllegalArgumentException e) {
// handle nested type: fall back to Types.fromTypeName and branch on nested types
} Prevention
- Check type.isPrimitiveType() when handling unknown column types
- Treat variant, struct, list, and map columns in a separate code path
- Prefer Types.fromTypeName when nested types are acceptable
When it happens
Trigger: Calling Types.fromPrimitiveString("variant") (or any type name that maps to a nested type such as a list/map/struct identifier) — the string parses fine but is not a PrimitiveType.
Common situations: Code that assumes a column is primitive (e.g. building predicates or ID-to-type maps) encountering a variant or other nested column type defined in the schema.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Cannot create expression literal from %s: %s
- Unsupported type: + type
- Unsupported binary type: + value.getClass()
- Cannot parse type string to primitive: + typeString
- Unsupported primitive type:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/6dcdaf3bb2ec5357.
Report an issue: GitHub.