{"record":{"id":"f80815c09ddf648b","repo":"apache/druid","slug":"batched-segment-allocation-is-disabled-f80815","errorCode":null,"errorMessage":"Batched segment allocation is disabled.","messagePattern":"Batched segment allocation is disabled\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentAllocationQueue.java","lineNumber":219,"sourceCode":"\n  /**\n   * Gets the number of batches currently in the queue.\n   */\n  public int size()\n  {\n    return processingQueue.size();\n  }\n\n  /**\n   * Queues a SegmentAllocateRequest. The returned future may complete successfully\n   * with a non-null value or with a non-null value.\n   */\n  public Future<SegmentIdWithShardSpec> add(SegmentAllocateRequest request)\n  {\n    if (!isLeader.get()) {\n      throw new ISE(\"Cannot allocate segment if not leader.\");\n    } else if (!isEnabled()) {\n      throw new ISE(\"Batched segment allocation is disabled.\");\n    }\n\n    final AllocateRequestKey requestKey = new AllocateRequestKey(request);\n    final AtomicReference<Future<SegmentIdWithShardSpec>> futureReference = new AtomicReference<>();\n\n    // Possible race condition:\n    // t1 -> new batch is added to queue or batch already exists in queue\n    // t2 -> executor pops batch, processes all requests in it\n    // t1 -> new request is added to dangling batch and is never picked up\n    // Solution: Perform the following operations only inside keyToBatch.compute():\n    // 1. Add or remove from map\n    // 2. Add batch to queue\n    // 3. Mark batch as started\n    // 4. Update requests in batch\n    keyToBatch.compute(requestKey, (key, existingBatch) -> {\n      if (existingBatch == null || existingBatch.isStarted() || existingBatch.isFull()) {\n        AllocateRequestBatch newBatch = new AllocateRequestBatch(key);\n        futureReference.set(newBatch.add(request));","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentAllocationQueue.java#L201-L237","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set druid.indexer.tasklock.batchedSegmentAllocation=true consistently on all Overlords and restart them.","Add the datasource to druid.indexer.tasklock.batchedSegmentAllocation.allowList.","Disable batched allocation in the task/ingestion spec if the cluster intentionally runs with the feature off.","Audit Overlord runtime.properties for config drift across the group."],"exampleFix":"// before (Overlord runtime.properties)\ndruid.indexer.tasklock.batchedSegmentAllocation=false\n// after\ndruid.indexer.tasklock.batchedSegmentAllocation=true\ndruid.indexer.tasklock.batchedSegmentAllocation.allowList=[\"kafka-ds\"]","handlingStrategy":"validation","validationCode":"boolean enabled = Boolean.parseBoolean(\n  System.getProperty(\"druid.indexer.tasklock.batchedSegmentAllocation\", \"false\"));\nif (!enabled) { /* enable flag or use non-batched allocation */ }","typeGuard":null,"tryCatchPattern":"try { future = queue.add(request); } catch (ISE e) { if (e.getMessage().contains(\"disabled\")) { /* enable flag or fallback path */ } else throw e; }","preventionTips":["Keep batchedSegmentAllocation identical on all Overlords.","Maintain the datasource allowList alongside supervisor configs.","Re-check flags after rolling upgrades and config rollbacks.","Document the flag as a prerequisite for supervisor-based ingestion."],"tags":["druid","segment-allocation","feature-flag","overlord"],"backgroundTag":"feature-not-enabled","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}