apache/iceberg · error · ValidationException
IsNaN cannot be used with a non-floating-point column
Error message
IsNaN cannot be used with a non-floating-point column
What it means
Iceberg's IS_NAN predicate is only meaningful for float and double columns. When an UnboundPredicate with Operation.IS_NAN is bound against a struct whose term resolves to a non-floating-point type, binding fails with this ValidationException rather than producing a predicate that can never be true.
Source
Thrown at api/src/main/java/org/apache/iceberg/expressions/UnboundPredicate.java:148
&& allAncestorFieldsAreRequired(struct, boundTerm.ref().fieldId())) {
return Expressions.alwaysFalse();
} else if (boundTerm.type().equals(Types.UnknownType.get())) {
return Expressions.alwaysTrue();
}
return new BoundUnaryPredicate<>(Operation.IS_NULL, boundTerm);
case NOT_NULL:
if (!boundTerm.producesNull()
&& allAncestorFieldsAreRequired(struct, boundTerm.ref().fieldId())) {
return Expressions.alwaysTrue();
} else if (boundTerm.type().equals(Types.UnknownType.get())) {
return Expressions.alwaysFalse();
}
return new BoundUnaryPredicate<>(Operation.NOT_NULL, boundTerm);
case IS_NAN:
if (floatingType(boundTerm.type().typeId())) {
return new BoundUnaryPredicate<>(Operation.IS_NAN, boundTerm);
} else {
throw new ValidationException("IsNaN cannot be used with a non-floating-point column");
}
case NOT_NAN:
if (floatingType(boundTerm.type().typeId())) {
return new BoundUnaryPredicate<>(Operation.NOT_NAN, boundTerm);
} else {
throw new ValidationException("NotNaN cannot be used with a non-floating-point column");
}
default:
throw new ValidationException("Operation must be IS_NULL, NOT_NULL, IS_NAN, or NOT_NAN");
}
}
private boolean allAncestorFieldsAreRequired(StructType struct, int fieldId) {
return TypeUtil.ancestorFields(struct.asSchema(), fieldId).stream()
.allMatch(Types.NestedField::isRequired);
}
private boolean floatingType(Type.TypeID typeID) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use isNaN only for float/double columns; use isNull for other types
- Check the field type in the table schema before building the predicate and choose the operation accordingly
- Fix the query/filter to target the correct column or drop the NaN check for non-float columns
Example fix
// before
Expression e = Expressions.isNaN("int_col");
// after
Types.NestedField f = schema.findField("int_col");
Expression e = (f.type().typeId() == Type.TypeID.FLOAT || f.type().typeId() == Type.TypeID.DOUBLE)
? Expressions.isNaN("int_col")
: Expressions.isNull("int_col"); Defensive patterns
Strategy: validation
Validate before calling
Type t = schema.findType("col");
boolean ok = t instanceof Types.FloatType || t instanceof Types.DoubleType;
if (!ok) throw new IllegalArgumentException("isNaN requires float/double column"); Type guard
static boolean isFloating(Type t) { return t.typeId() == Type.TypeID.FLOAT || t.typeId() == Type.TypeID.DOUBLE; } Try / catch
try { Expression bound = Binder.bind(struct, Expressions.isNaN("col"), true); } catch (ValidationException e) { /* fall back to isNull or reject the filter */ } Prevention
- Look up the field type before constructing NaN predicates
- Use isNaN only for float/double columns; notNull/int columns get isNull
- Re-validate stored filters after schema type changes
When it happens
Trigger: Expressions.isNull/isNaN-style filter: e.g. Expressions.isNaN("int_col") or filter("isNaN(id)") where the referenced field is int, long, decimal, string, timestamp, etc., then binding the expression to a table schema.
Common situations: User-submitted SQL with IS NAN on integer columns; query builders that emit isNaN generically for numeric fields; schema evolution changing a column from double to a non-float type while old NaN filters remain.
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
- NotNaN cannot be used with a non-floating-point column
- Operation must be IS_NULL, NOT_NULL, IS_NAN, or NOT_NAN
- Invalid value for conversion to type %s: %s (%s)
- Visitor %s does not support non-reference: %s
- Cannot get NaN value for type
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/52f71ebe2dcd36f3.
Report an issue: GitHub.