apache/druid · error · IllegalArgumentException

maxActiveProcessors[%d] < 1

Error message

maxActiveProcessors[%d] < 1

What it means

The SuperSorter constructor validates its concurrency configuration before building the sort pipeline. maxActiveProcessors controls how many FrameProcessors may run concurrently; a value below 1 would stall the sorter (no processor could ever be scheduled), so an IAE is thrown eagerly. This is a fail-fast configuration validation.

Source

Thrown at processing/src/main/java/org/apache/druid/frame/processor/SuperSorter.java:269

    this.exec = exec;
    this.processorDecorator = processorDecorator;
    this.outputChannelFactory = outputChannelFactory;
    this.intermediateOutputChannelFactory = intermediateOutputChannelFactory;
    this.outputFrameType = outputFrameType;
    this.maxChannelsPerMerger = maxChannelsPerMerger;
    this.maxActiveProcessors = maxActiveProcessors;
    this.rowLimit = rowLimit;
    this.cancellationId = cancellationId;
    this.superSorterProgressTracker = superSorterProgressTracker;
    this.removeNullBytes = removeNullBytes;
    this.combinerFactory = combinerFactory;

    for (int i = 0; i < inputChannels.size(); i++) {
      inputChannelsToRead.add(i);
    }

    if (maxActiveProcessors < 1) {
      throw new IAE("maxActiveProcessors[%d] < 1", maxActiveProcessors);
    }

    if (maxChannelsPerMerger < 2) {
      throw new IAE("maxChannelsPerMerger[%d] < 2", maxChannelsPerMerger);
    }

    if (rowLimit != UNLIMITED && rowLimit <= 0) {
      throw new IAE("rowLimit[%d] must be positive", rowLimit);
    }
  }

  /**
   * Starts sorting. Can only be called once. Work is performed in the {@link FrameProcessorExecutor} that was
   * passed to the constructor.
   *
   * Returns a future containing partitioned sorted output channels.
   */
  public ListenableFuture<OutputChannels> run()

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Set maxActiveProcessors to at least 1 (in practice the number of frame processor threads, e.g. druid_processing_numThreads) in the server configuration
  2. Fix the code that computes the limit so it clamps to Math.max(1, computed)
  3. Verify the constructor call site passes arguments in the correct order (processors limit vs maxChannelsPerMerger)

Example fix

// before
new SuperSorter(inputChannels, allowInputReading, maxActiveProcessors = 0, maxChannelsPerMerger, ...);
// after
new SuperSorter(inputChannels, allowInputReading, Math.max(1, configuredMaxActiveProcessors), maxChannelsPerMerger, ...);
Defensive patterns

Strategy: validation

Validate before calling

if (maxActiveProcessors < 1) { throw new IllegalArgumentException("maxActiveProcessors must be >= 1, got " + maxActiveProcessors); }

Try / catch

try { sorter = new SuperSorter(...); } catch (IllegalArgumentException e) { if (!e.getMessage().contains("maxActiveProcessors")) throw e; log.error("Fix frame processor concurrency config: %s", e.getMessage()); }

Prevention

When it happens

Trigger: Constructing SuperSorter with maxActiveProcessors = 0 or negative — typically from a misconfigured query-time setting such as a server config that sets the frame processor concurrency to 0, or arithmetic that computes the limit as available processors minus something and underflows.

Common situations: Druid cluster config with numThreads/maxActiveProcessors set to 0 or negative in runtime.properties; code computing the limit from a quota or CPU count that resolves to 0 in a constrained container; passing the wrong argument position to the constructor.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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