apache/druid · error · ExpressionValidationException
Possible data truncation, param
Error message
Possible data truncation, param [%f] is out of LONG value range
What it means
Thrown by the BitwiseComplement (~) vector expression processor when its double-typed input is outside the range of a Java long. Applying bitwise complement to a value that cannot be losslessly narrowed to a long would silently truncate the data, so Druid fails fast with an ExpressionValidationException naming the offending parameter value.
Solutions
- Cast or round the input to a long before applying `~` in the expression (e.g. use CAST(x AS BIGINT) or explicit long math).
- Change the column's SQL type in the ingestion spec to 'long' if the underlying data is integral, so the vector processor receives long inputs directly.
- Clamp or validate the data upstream so values stay within [-9223372036854775808, 9223372036854775807].
- If the value legitimately exceeds long range, drop the bitwise operation; `~` is not meaningful for such magnitudes.
Example fix
// before: ~x on a double column with huge values -> ExpressionValidationException // after "expression": "~CAST(x AS BIGINT)" // or store x as a long column in the ingestion spec
Defensive patterns
Strategy: validation
Validate before calling
// validate before building the expression
if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
throw new IllegalArgumentException("~ requires value within LONG range, got: " + value);
} Type guard
boolean inLongRange(double v) {
return v >= (double) Long.MIN_VALUE && v <= (double) Long.MAX_VALUE;
} Try / catch
try {
result = expr.eval(bindings);
} catch (ExpressionValidationException e) {
if (e.getMessage().contains("out of LONG value range")) {
result = null; // or clamp/coerce
} else {
throw e;
}
} Prevention
- Store integral data as 'long' columns, not 'double', when bitwise operators will be used.
- CAST to BIGINT in expressions before applying ~ or other bitwise functions.
- Validate upstream data ranges at ingestion time for columns feeding bitwise expressions.
When it happens
Trigger: Evaluating a Druid expression like `~x` (BitwiseComplement) in a vectorized query where the input column or expression yields a double outside [Long.MIN_VALUE, Long.MAX_VALUE] (e.g. values >= 2^63 or <= -2^63, including from large numeric columns or division results).
Common situations: Bitwise operators applied to double-valued columns that contain very large magnitudes; ingesting numbers as 'double' but then using `~` on them; comparing timestamps stored as doubles since epoch millis; passing floats where longs are expected.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- attempt to get boolean[] null vector from string[] only…
- attempt to get double[] from string[] only scalar binding
- attempt to get long[] from string[] only scalar binding
- Selector must have a dictionary
- Selector of class[ ] does not have a dictionary, cannot use…
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/1507a33ef807b773.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java:827
public Ulp()
{
super(l -> Math.ulp((double) l), Math::ulp);
}
}
public static final class BitwiseComplement extends SimpleVectorMathUnivariateLongProcessorFactory
{
private static final BitwiseComplement INSTANCE = new BitwiseComplement();
public BitwiseComplement()
{
super(
input -> ~input,
input -> {
if (input < Long.MIN_VALUE || input > Long.MAX_VALUE) {
throw new ExpressionValidationException(
Function.BitwiseComplement.NAME,
"Possible data truncation, param [%f] is out of LONG value range",
input
);
}
return ~((long) input);
}
);
}
}
public static class BitwiseConvertDoubleToLongBits extends SimpleVectorMathUnivariateLongProcessorFactory
{
private static final BitwiseConvertDoubleToLongBits INSTANCE = new BitwiseConvertDoubleToLongBits();
public BitwiseConvertDoubleToLongBits()
{
super(Double::doubleToLongBits, Double::doubleToLongBits);View on GitHub (pinned to 9b90983fd2)