apache/druid · error · IllegalArgumentException

Cannot have empty worker set

Error message

Cannot have empty worker set

What it means

ReadablePartition records which workers hold a given input partition; an empty worker set is meaningless because MSQ needs at least one worker to read each partition. The constructor validates this with an IAE.

Source

Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/input/stage/ReadablePartition.java:45

/**
 * Represents an output partition associated with a particular stage. Each partition is readable from one or
 * more workers.
 */
public class ReadablePartition
{
  private final int stageNumber;
  private final IntSortedSet workerNumbers;
  private final int partitionNumber;

  private ReadablePartition(final int stageNumber, final IntSortedSet workerNumbers, final int partitionNumber)
  {
    this.stageNumber = stageNumber;
    this.workerNumbers = workerNumbers;
    this.partitionNumber = partitionNumber;

    if (workerNumbers.isEmpty()) {
      throw new IAE("Cannot have empty worker set");
    }
  }

  /**
   * Returns an output partition that is striped across {@code numWorkers} workers.
   */
  public static ReadablePartition striped(final int stageNumber, final int numWorkers, final int partitionNumber)
  {
    final IntAVLTreeSet workerNumbers = new IntAVLTreeSet();
    for (int i = 0; i < numWorkers; i++) {
      workerNumbers.add(i);
    }

    return new ReadablePartition(stageNumber, workerNumbers, partitionNumber);
  }

  /**
   * Returns an output partition that is striped across a set of {@code workerNumbers}.

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Ensure the worker assignment code only creates ReadablePartitions for partitions actually assigned to >= 1 worker.
  2. Verify the MSQ cluster has at least one available worker (middleManager/indexer capacity) before submitting queries.
  3. In tests, pass a non-empty worker set, e.g. ImmutableSet.of(0).

Example fix

// before
new ReadablePartition(stageNumber, ImmutableSet.of(), partitionNumber);
// after
new ReadablePartition(stageNumber, ImmutableSet.of(0), partitionNumber);
Defensive patterns

Strategy: validation

Validate before calling

if (workerNumbers == null || workerNumbers.isEmpty()) {
  throw new IllegalArgumentException("workerNumbers must be non-empty");
}
ReadablePartition p = new ReadablePartition(stageNumber, workerNumbers, partitionNumber);

Try / catch

try {
  return new ReadablePartition(stageNumber, workerNumbers, partitionNumber);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().equals("Cannot have empty worker set")) {
    log.warn("Skipping partition with no assigned workers");
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: Constructing ReadablePartition (directly in tests or via shuffle-spec/partition assignment code) with an empty workerNumbers set - e.g. when partition assignment logic assigns no workers because maxNumSlices is 0 or the worker list was empty.

Common situations: Custom shuffle strategies or unit tests passing an empty ImmutableSet/ImmutableList of workers; cluster had zero workers so the assignment produced empty sets.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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