apache/druid · error · IllegalArgumentException

Cannot join lookup with condition referring to non-key colum

Error message

Cannot join lookup with condition referring to non-key column: %s

What it means

Lookup joins require all equi-conditions on the right side to reference the lookup's designated key column (LookupColumnSelectorFactory.KEY_COLUMN). If a condition refers to any other lookup column, LookupJoinMatcher.create throws this IllegalArgumentException since only the key can be matched.

Source

Thrown at processing/src/main/java/org/apache/druid/segment/join/lookup/LookupJoinMatcher.java:198

  public static LookupJoinMatcher create(
      LookupExtractor extractor,
      ColumnSelectorFactory leftSelectorFactory,
      JoinConditionAnalysis condition,
      boolean remainderNeeded
  )
  {
    final List<Expr> keyExprs;

    if (condition.isAlwaysTrue()) {
      keyExprs = null;
    } else if (condition.isAlwaysFalse()) {
      keyExprs = null;
    } else if (!condition.getNonEquiConditions().isEmpty()) {
      throw new IAE("Cannot join lookup with non-equi condition: %s", condition);
    } else if (!condition.getRightEquiConditionKeys()
                         .stream()
                         .allMatch(LookupColumnSelectorFactory.KEY_COLUMN::equals)) {
      throw new IAE("Cannot join lookup with condition referring to non-key column: %s", condition);
    } else {
      keyExprs = condition.getEquiConditions().stream().map(Equality::getLeftExpr).collect(Collectors.toList());
    }

    return new LookupJoinMatcher(extractor, leftSelectorFactory, condition, keyExprs, remainderNeeded);
  }

  @Override
  public ColumnSelectorFactory getColumnSelectorFactory()
  {
    return selectorFactory;
  }

  @Override
  public void matchCondition()
  {
    currentIterator = null;
    matchingRemainder = false;

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Rewrite the join so it equates on the lookup's key column only
  2. Create a new lookup keyed by the column you actually want to join on
  3. If using SQL, join against the lookup's key (usually exposed as the lookup key) rather than a value column

Example fix

// before
JOIN lookup l ON t.k = l.value_col
// after
JOIN lookup l ON t.k = l.__key -- or create a lookup keyed by value_col
Defensive patterns

Strategy: validation

Validate before calling

boolean ok = condition.getRightEquiConditionKeys().stream()
  .allMatch(LookupColumnSelectorFactory.KEY_COLUMN::equals);
if (!ok) throw new IllegalArgumentException("lookup join must reference key column");

Try / catch

try { LookupJoinMatcher.create(...); } catch (IAE e) { /* rewrite to key column or create appropriately keyed lookup */ }

Prevention

When it happens

Trigger: Creating a LookupJoinMatcher with an equi condition whose right-hand key is not the lookup key column, e.g. ON t.k = l.some_other_column.

Common situations: SQL joining a lookup on a non-key column of the lookup; generated native join clauses referencing lookup value columns instead of __key; lookup registered with unexpected key naming after refactoring.

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


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