{"record":{"id":"6aea7f946c6d4114","repo":"apache/druid","slug":"task-s-already-exists-in-taskgroup-d-with-data","errorCode":null,"errorMessage":"Task[%s] already exists in taskGroup[%d] with data[%s]","messagePattern":"Task\\[(.+?)\\] already exists in taskGroup\\[(.+?)\\] with data\\[(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisor.java","lineNumber":2584,"sourceCode":"                                          seekableStreamIndexTask.getIOConfig()\n                                                                 .getStartSequenceNumbers()\n                                                                 .getPartitionSequenceNumberMap()\n                                      ),\n                                      null,\n                                      endSequences,\n                                      seekableStreamIndexTask.getIOConfig().getMinimumMessageTime(),\n                                      seekableStreamIndexTask.getIOConfig().getMaximumMessageTime(),\n                                      seekableStreamIndexTask.getIOConfig()\n                                                             .getStartSequenceNumbers()\n                                                             .getExclusivePartitions(),\n                                      seekableStreamIndexTask.getIOConfig().getBaseSequenceName()\n                                  );\n                                }\n                            );\n                            taskGroupsToVerify.put(taskGroupId, taskGroup);\n                            final TaskData prevTaskData = taskGroup.tasks.putIfAbsent(taskId, new TaskData());\n                            if (prevTaskData != null) {\n                              throw new ISE(\n                                  \"Task[%s] already exists in taskGroup[%d] with data[%s]\",\n                                  taskId, taskGroup.groupId, prevTaskData\n                              );\n                            }\n                            final Integer serverPriority = seekableStreamIndexTask.getServerPriority();\n                            if (serverPriority != null) {\n                              taskGroup.taskIdToServerPriority.putIfAbsent(taskId, serverPriority);\n                            }\n                            verifySameSequenceNameForAllTasksInGroup(taskGroupId);\n                          }\n                        }\n                        return true;\n                      }\n                      catch (Throwable t) {\n                        stateManager.recordThrowableEvent(t);\n                        log.error(t, \"An error occurred while discovering task[%s]\", taskId);\n                        return null;\n                      }","sourceCodeStart":2566,"sourceCodeEnd":2602,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisor.java#L2566-L2602","documentation":"When the supervisor discovers running tasks (in its task management/run loop), it registers each task into its task group's TaskData map with putIfAbsent. A non-null previous value means the same task id is already registered, implying either a duplicate task launch or state corruption, so an ISE is thrown to surface the inconsistency.","triggerScenarios":"Two tasks with identical ids assigned to the same task group — typically caused by duplicate task creation during supervisor restart/race, or the same task being discovered twice by concurrent discovery paths with stale TaskData present.","commonSituations":"Overlord/task queue duplicate submissions after supervisor failover; leftover task records in metadata storage causing re-discovery of terminated tasks; concurrent supervisor leadership transitions (HA supervisor runners).","solutions":["Kill the duplicate/stale task via the overlord task API so only one instance remains","Restart the supervisor to rebuild task group state from authoritative task lists","Check for multiple active supervisor leaders or overlapping supervisor restarts; ensure single leadership","Clean orphaned task rows in the metadata storage if re-discovery keeps resurrecting old tasks"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"if (taskGroup.tasks.containsKey(taskId)) {\n  log.warn(\"Task %s already registered in group %s; skipping duplicate registration\", taskId, taskGroup.groupId);\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  supervisor.registerDiscoveredTask(taskId, taskGroup);\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Task[\")) {\n    // duplicate task; kill the stale instance and restart the supervisor\n  } else throw e;\n}","preventionTips":["Ensure a single active supervisor leader per datasource","Kill duplicate tasks via the overlord API when observed","Purge orphaned task rows from metadata storage after failover"],"tags":["supervisor","duplicate-task","race-condition"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}