apache/druid · error · IllegalStateException
Expected [%s], but [%s] is in use
Error message
Expected [%s], but [%s] is in use
What it means
Thrown by an HTTP endpoint on ParallelIndexSupervisorTask (e.g. the /subtaskspecs or related REST API) when the currently active runner is not a SinglePhaseParallelIndexTaskRunner. Those endpoints only make sense for single-phase parallel ingestion; calling them on a task running a different runner is an invalid request.
Source
Thrown at indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTask.java:1404
*/
@POST
@Path("/segment/allocate")
@Produces(SmileMediaTypes.APPLICATION_JACKSON_SMILE)
@Consumes(SmileMediaTypes.APPLICATION_JACKSON_SMILE)
public Response allocateSegment(
Object param,
@Context final HttpServletRequest req
)
{
ChatHandlers.authorizationCheck(req, Action.READ, getDataSource(), authorizerMapper);
if (toolbox == null) {
return Response.status(Response.Status.SERVICE_UNAVAILABLE).entity("task is not running yet").build();
}
ParallelIndexTaskRunner runner = Preconditions.checkNotNull(getCurrentRunner(), "runner");
if (!(runner instanceof SinglePhaseParallelIndexTaskRunner)) {
throw new ISE(
"Expected [%s], but [%s] is in use",
SinglePhaseParallelIndexTaskRunner.class.getName(),
runner.getClass().getName()
);
}
// This context is set in the constructor of ParallelIndexSupervisorTask if it's not set by others.
final boolean useLineageBasedSegmentAllocation = Preconditions.checkNotNull(
getContextValue(SinglePhaseParallelIndexTaskRunner.CTX_USE_LINEAGE_BASED_SEGMENT_ALLOCATION_KEY),
"useLineageBasedSegmentAllocation in taskContext"
);
try {
final SegmentIdWithShardSpec segmentIdentifier;
if (useLineageBasedSegmentAllocation) {
SegmentAllocationRequest request = toolbox.getJsonMapper().convertValue(param, SegmentAllocationRequest.class);
segmentIdentifier = ((SinglePhaseParallelIndexTaskRunner) runner)
.allocateNewSegment(View on GitHub (pinned to 9b90983fd2)
Solutions
- Only call subtask-spec endpoints on tasks using SinglePhaseParallelIndexTaskRunner; check the task type first.
- For multi-phase tasks use the appropriate endpoints (/subtaskspecs vs phase-specific APIs) or the overlord task report.
- Update monitoring scripts to branch on task 'type' (index_parallel vs index/replace).
Example fix
// before curl $OVERLORD/druid/indexer/v1/task/$taskId/subtaskspecs // after: only for index_parallel tasks type=$(curl $OVERLORD/druid/indexer/v1/task/$taskId | jq -r .payload.type) if [ "$type" = "index_parallel" ]; then curl $OVERLORD/druid/indexer/v1/task/$taskId/subtaskspecs fi
Defensive patterns
Strategy: type-guard
Type guard
function canQuerySubtaskSpecs(taskType) {
return taskType === 'index_parallel';
} Prevention
- Check task 'type' before calling subtask-spec REST endpoints
- Branch monitoring scripts on task type (index_parallel vs index/replace)
- Handle HTTP 500 with the 'Expected [%s], but [%s] is in use' message as 'endpoint not applicable'
When it happens
Trigger: Hitting task REST endpoints like /druid/indexer/v1/task/{id}/subtaskspecs or /unparseableEvents (subtask spec APIs) against a task whose runner is a two-phase/sequential runner (e.g. runTask via SQL-generated replace tasks).
Common situations: Scripts or UI integrations that query subtask APIs for every batch task regardless of its type; monitoring tools pointing at compaction or MSQ replace tasks that use other runners.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- User [%s] does not exist.
- User [%s] already exists.
- Group mapping [%s] does not exist.
- Group mapping [%s] already exists.
- Role [%s] already exists.
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/d24ba876a60ec35f.
Report an issue: GitHub.