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

  1. Pass the lookup name as a quoted string literal: LOOKUP(col, 'country_code_to_name').
  2. Confirm the lookup is actually registered in the cluster (the name must be non-null and resolvable by the lookup coordinator).
  3. 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

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


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/8c43eab3d8111a04. Report an issue: GitHub.