apache/druid · error · DruidException
second argument must be a registered lookup name
Error message
second argument must be a registered lookup name
What it means
The LOOKUP expression macro's second argument must be a non-null string literal naming a registered lookup. Druid throws a validation failure when the literal is null (or otherwise not a usable lookup name), because the macro compiles to a RegisteredLookupExtractionFn that needs a concrete lookup name at compile time.
Source
Thrown at processing/src/main/java/org/apache/druid/query/expression/LookupExprMacro.java:69
@Override
public String name()
{
return FN_NAME;
}
@Override
public Expr apply(final List<Expr> args)
{
validationHelperCheckArgumentRange(args, 2, 3);
final Expr arg = args.get(0);
final Expr lookupExpr = args.get(1);
final Expr replaceMissingValueWith = getReplaceMissingValueWith(args);
validationHelperCheckArgIsLiteral(lookupExpr, "second argument");
if (lookupExpr.getLiteralValue() == null) {
throw validationFailed("second argument must be a registered lookup name");
}
final String lookupName = lookupExpr.getLiteralValue().toString();
final RegisteredLookupExtractionFn extractionFn = new RegisteredLookupExtractionFn(
lookupExtractorFactoryContainerProvider,
lookupName,
false,
replaceMissingValueWith != null && replaceMissingValueWith.isLiteral()
? Evals.asString(replaceMissingValueWith.getLiteralValue())
: null,
null,
null
);
class LookupExpr extends ExprMacroTable.BaseScalarMacroFunctionExpr
{
private LookupExpr(final List<Expr> args)
{View on GitHub (pinned to 9b90983fd2)
Solutions
- Pass the lookup name as a quoted string literal: LOOKUP(col, 'country_code_to_name').
- Confirm the lookup is actually registered in the cluster (the name must be non-null and resolvable by the lookup coordinator).
- Fix the query generator/template so the lookup-name variable is populated before query submission.
Example fix
-- before SELECT LOOKUP(country, NULL) FROM t -- after SELECT LOOKUP(country, 'country_code_to_name') FROM t
Defensive patterns
Strategy: validation
Validate before calling
// JS/TS before emitting SQL
if (typeof lookupName !== 'string' || lookupName.length === 0) throw new Error('LOOKUP requires a registered lookup name literal'); Type guard
function isLookupName(x) { return typeof x === 'string' && x.trim().length > 0; } Try / catch
try {
return runDruidQuery(query);
} catch (ExpressionValidationException e) {
if (e.getMessage().contains("registered lookup name")) {
throw new UserInputException("LOOKUP second argument must be a non-null lookup name string");
}
throw e;
} Prevention
- Always quote the lookup name as a string literal in SQL.
- Resolve lookup-name template variables before query submission.
- Verify lookup registration (coordination service) before using a name in queries.
When it happens
Trigger: Calling LOOKUP(col, <literal>) where the second argument's literal value is null, e.g. LOOKUP(col, NULL), or passing a non-literal (column/expression) as the lookup name, or an unquoted identifier that evaluates to null.
Common situations: Generated SQL where the lookup name came from an empty config/template variable; users trying to parameterize the lookup name with a column reference; SQL NULL literals submitted for the lookup argument.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Invalid expression: %s; %s used as both scalar and array var
- rank must be a number
- subnet arg has an invalid format: %s
- subnet arg has an invalid format: %s
- escape must be null or a single character
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/8c43eab3d8111a04.
Report an issue: GitHub.