apache/druid · error · java.lang.IllegalArgumentException

Unknown sketch operation

Error message

Unknown sketch operation 

What it means

sketchSetOperation() switches over the Func enum (UNION, INTERSECT, NOT). The default branch throws for any value it does not recognize, which can only occur if a Func constant was added by a newer datasketches extension than the code executing, or a null/unexpected func was coerced into the switch.

Solutions

  1. Use only supported func values: UNION, INTERSECT, NOT in query JSON
  2. Upgrade the Druid cluster uniformly so all nodes recognize the same set of Func values
  3. Check for recently added Func constants and update the switch in sketchSetOperation to handle them

Example fix

// before
String func = "A_NOT_B"; // invalid in query JSON
// after
String func = "NOT"; // supported: UNION, INTERSECT, NOT
Defensive patterns

Strategy: validation

Validate before calling

Set<String> allowed = Set.of("UNION", "INTERSECT", "NOT");
if (funcStr == null || !allowed.contains(funcStr)) {
  throw new IllegalArgumentException("Unsupported sketch set op: " + funcStr);
}

Type guard

boolean isSupportedFunc(String s) {
  return "UNION".equals(s) || "INTERSECT".equals(s) || "NOT".equals(s);
}

Try / catch

try {
  SketchHolder r = SketchHolder.sketchSetOperation(Func.valueOf(funcStr), size, holders);
} catch (IllegalArgumentException e) {
  // bad func name; surface a query-validation error to the user
}

Prevention

When it happens

Trigger: Calling SketchHolder.sketchSetOperation(func, size, holders) where func is a Func value not handled by this switch — most commonly when Func was parsed from an unknown user-supplied string via Func.valueOf elsewhere, adding a new enum constant without updating this switch.

Common situations: Query JSON containing an unrecognized 'func' for a SketchSetPostAggregator; a version skew where a newer Druid serialized query references a Func the running nodes don't implement; typos like 'NOT_B' instead of 'NOT' caught earlier by valueOf but mapping to an unhandled constant.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/SketchHolder.java:311

        }
        return SketchHolder.of(intersection.getResult(false, null));
      case NOT:
        if (holders.length < 1) {
          throw new IllegalArgumentException("A-Not-B requires at least 1 sketch");
        }

        if (holders.length == 1) {
          return (SketchHolder) holders[0];
        }

        Sketch result = ((SketchHolder) holders[0]).getSketch();
        for (int i = 1; i < holders.length; i++) {
          AnotB anotb = (AnotB) SetOperation.builder().setNominalEntries(sketchSize).build(Family.A_NOT_B);
          result = anotb.aNotB(result, ((SketchHolder) holders[i]).getSketch());
        }
        return SketchHolder.of(result);
      default:
        throw new IllegalArgumentException("Unknown sketch operation " + func);
    }
  }

  /**
   *  Ideally make use of Sketch's equals and hashCode methods but which are not value based implementations.
   *  And yet need value based equals and hashCode implementations for SketchHolder. 
   *  Hence using Arrays.equals() and Arrays.hashCode().
   */
  @Override
  public boolean equals(Object o)
  {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    return Arrays.equals(this.getSketch().toByteArray(), ((SketchHolder) o).getSketch().toByteArray());

View on GitHub (pinned to 9b90983fd2)