apache/druid · error · IllegalArgumentException

Cannot join lookup with condition referring to non-key…

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.

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.

Appendix: 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)