apache/druid · error · IllegalStateException

Batched segment allocation is disabled.

Error message

Batched segment allocation is disabled.

What it means

SegmentAllocationQueue.add() checks isEnabled() after the leader check; if the batched-allocation feature (druid.indexer.tasklock.batchedSegmentAllocation plus datasource allow list) is off, the queue refuses to accept requests and throws this ISE. It is the queue-level duplicate of the guard in SegmentAllocateAction.performAsync.

Source

Thrown at indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentAllocationQueue.java:219

  /**
   * Gets the number of batches currently in the queue.
   */
  public int size()
  {
    return processingQueue.size();
  }

  /**
   * Queues a SegmentAllocateRequest. The returned future may complete successfully
   * with a non-null value or with a non-null value.
   */
  public Future<SegmentIdWithShardSpec> add(SegmentAllocateRequest request)
  {
    if (!isLeader.get()) {
      throw new ISE("Cannot allocate segment if not leader.");
    } else if (!isEnabled()) {
      throw new ISE("Batched segment allocation is disabled.");
    }

    final AllocateRequestKey requestKey = new AllocateRequestKey(request);
    final AtomicReference<Future<SegmentIdWithShardSpec>> futureReference = new AtomicReference<>();

    // Possible race condition:
    // t1 -> new batch is added to queue or batch already exists in queue
    // t2 -> executor pops batch, processes all requests in it
    // t1 -> new request is added to dangling batch and is never picked up
    // Solution: Perform the following operations only inside keyToBatch.compute():
    // 1. Add or remove from map
    // 2. Add batch to queue
    // 3. Mark batch as started
    // 4. Update requests in batch
    keyToBatch.compute(requestKey, (key, existingBatch) -> {
      if (existingBatch == null || existingBatch.isStarted() || existingBatch.isFull()) {
        AllocateRequestBatch newBatch = new AllocateRequestBatch(key);
        futureReference.set(newBatch.add(request));

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Set druid.indexer.tasklock.batchedSegmentAllocation=true consistently on all Overlords and restart them.
  2. Add the datasource to druid.indexer.tasklock.batchedSegmentAllocation.allowList.
  3. Disable batched allocation in the task/ingestion spec if the cluster intentionally runs with the feature off.
  4. Audit Overlord runtime.properties for config drift across the group.

Example fix

// before (Overlord runtime.properties)
druid.indexer.tasklock.batchedSegmentAllocation=false
// after
druid.indexer.tasklock.batchedSegmentAllocation=true
druid.indexer.tasklock.batchedSegmentAllocation.allowList=["kafka-ds"]
Defensive patterns

Strategy: validation

Validate before calling

boolean enabled = Boolean.parseBoolean(
  System.getProperty("druid.indexer.tasklock.batchedSegmentAllocation", "false"));
if (!enabled) { /* enable flag or use non-batched allocation */ }

Try / catch

try { future = queue.add(request); } catch (ISE e) { if (e.getMessage().contains("disabled")) { /* enable flag or fallback path */ } else throw e; }

Prevention

When it happens

Trigger: A SEGMENT_ALLOCATE task action reaches the queue on an Overlord where the batched-allocation flag is false or the request's datasource is missing from druid.indexer.tasklock.batchedSegmentAllocation.allowList.

Common situations: Feature flag enabled on some Overlords but not others in the HA group; allowList edited after a supervisor was already running; config rolled back during an upgrade.

Related errors


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