apache/druid · error · DruidException
rank must be a number
Error message
rank must be a number
What it means
The ARRAY_QUANTILE expression macro requires its second argument ('rank') to be a literal number. Druid throws this ExprMacroTable validation error during expression compilation when the rank argument is a literal of a non-numeric type (e.g. a string), so the quantile function can never be evaluated.
Source
Thrown at processing/src/main/java/org/apache/druid/query/expression/ArrayQuantileExprMacro.java:67
private static final String RANK_ARG_NAME = "rank";
@Override
public String name()
{
return FN_NAME;
}
@Override
public Expr apply(final List<Expr> args)
{
validationHelperCheckArgumentCount(args, 2);
final Expr arg = args.get(0);
final Expr rankArg = args.get(1);
validationHelperCheckArgIsLiteral(rankArg, RANK_ARG_NAME);
if (!(rankArg.getLiteralValue() instanceof Number)) {
throw validationFailed("%s must be a number", RANK_ARG_NAME);
}
final double rank = ((Number) rankArg.getLiteralValue()).doubleValue();
class ArrayQuantileExpr extends ExprMacroTable.BaseScalarMacroFunctionExpr
{
private ArrayQuantileExpr(List<Expr> args)
{
super(ArrayQuantileExprMacro.this, args);
}
@Nonnull
@Override
public ExprEval<?> eval(final ObjectBinding bindings)
{
final DoubleList doubles = toDoubleArray(arg.eval(bindings));
if (doubles == null) {View on GitHub (pinned to 9b90983fd2)
Solutions
- Remove quotes from the rank argument so it is a numeric literal: ARRAY_QUANTILE(expr, 0.5).
- Ensure the rank argument is a literal constant, not a column or nested expression.
- Cast/convert the value to a number in the calling code before building the expression.
Example fix
-- before SELECT ARRAY_QUANTILE(arr, '0.5') FROM t -- after SELECT ARRAY_QUANTILE(arr, 0.5) FROM t
Defensive patterns
Strategy: validation
Validate before calling
// JS/TS before emitting SQL
if (typeof rank !== 'number' || Number.isNaN(rank)) throw new Error('ARRAY_QUANTILE rank must be a numeric literal'); Type guard
function isNumericLiteral(x) { return typeof x === 'number' && Number.isFinite(x); } Try / catch
try {
return runDruidQuery(query);
} catch (ExpressionValidationException e) {
if (e.getMessage().contains("rank must be a number")) {
throw new UserInputException("Quantile rank must be an unquoted number, e.g. 0.5");
}
throw e;
} Prevention
- Never quote numeric arguments in generated Druid expressions.
- Keep quantile ranks as constants, not column references.
- Validate user-provided percentiles in the application layer before building queries.
When it happens
Trigger: Calling ARRAY_QUANTILE(expr, '0.5') in a Druid SQL/expression selector where the rank is quoted as a string; passing a non-literal (column reference) as rank; passing a literal boolean or null as the second argument.
Common situations: Hand-written SQL with quoted percentile values ('0.9'); generated SQL from BI tools that quotes all function arguments; users expecting the rank to be a column instead of a constant.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid expression: %s; %s used as both scalar and array var
- subnet arg has an invalid format: %s
- subnet arg has an invalid format: %s
- escape must be null or a single character
- second argument must be a registered lookup name
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/06a2623c3b35102e.
Report an issue: GitHub.