{"record":{"id":"3374af192ec7b869","repo":"apache/druid","slug":"can-t-start-3374af","errorCode":null,"errorMessage":"can't start.","messagePattern":"can't start\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/LeaderElectorAsyncWrapper.java","lineNumber":72,"sourceCode":"        K8sDiscoveryConfig.K8S_RESOURCE_NAME_REGEX.matcher(lockResourceName).matches(),\n        \"lockResourceName[%s] must match regex[%s]\",\n        lockResourceName,\n        K8sDiscoveryConfig.K8S_RESOURCE_NAME_REGEX.pattern()\n    );\n    LOGGER.info(\n        \"Creating LeaderElector with candidateId[%s], lockResourceName[%s],  k8sNamespace[%s].\",\n        candidateId,\n        lockResourceName,\n        lockResourceNamespace\n    );\n\n    k8sLeaderElector = k8sLeaderElectorFactory.create(candidateId, lockResourceNamespace, lockResourceName);\n  }\n\n  public void run(Runnable startLeadingHook, Runnable stopLeadingHook)\n  {\n    if (!lifecycleLock.canStart()) {\n      throw new ISE(\"can't start.\");\n    }\n\n    try {\n      executor = Execs.singleThreaded(this.getClass().getSimpleName());\n      futureRef.set(executor.submit(\n          () -> {\n            while (lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)) {\n              try {\n                k8sLeaderElector.run(startLeadingHook, stopLeadingHook);\n              }\n              catch (Throwable ex) {\n                LOGGER.error(ex, \"Exception in K8s LeaderElector.run()\");\n              }\n            }\n          }\n      ));\n      lifecycleLock.started();\n    }","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/kubernetes-extensions/src/main/java/org/apache/druid/k8s/discovery/LeaderElectorAsyncWrapper.java#L54-L90","documentation":"LeaderElectorAsyncWrapper.run() throws this IllegalStateException when its LifecycleLock disallows start - i.e. the elector is already running, stopping, or was previously stopped. The wrapper submits the leader-election loop to a single-threaded executor exactly once; a second run() would create competing leadership callbacks.","triggerScenarios":"Calling run() twice on the same wrapper (e.g. re-election attempt after losing leadership); concurrent run() invocations; calling run() after close(); startLeaderElector invoked again by task-runner reconfiguration.","commonSituations":"Overlord candidate re-joining an election after a network blip while the old elector still exists; double injection of the leader-wrangler in Druid task-runner master election; unit tests reusing one wrapper across cases.","solutions":["Call run() once per LeaderElectorAsyncWrapper instance; create a new wrapper for re-election","Close the old elector and construct a fresh one before calling run() again","Synchronize callers (startLeaderElector) so run() cannot race with itself","Verify via logs - repeated 'LeaderElectorAsyncWrapper' thread creation means run() was called twice"],"exampleFix":"// before\nelector.run(leadHook, stopHook);\n// re-election\nelector.run(leadHook, stopHook); // ISE\n// after\nelector.close();\nelector = new LeaderElectorAsyncWrapper(...);\nelector.run(leadHook, stopHook);","handlingStrategy":"validation","validationCode":"if (electorRunning) { return; }","typeGuard":null,"tryCatchPattern":"try { elector.run(startLeadingHook, stopLeadingHook); } catch (IllegalStateException e) { log.warn(\"elector already running or closed\"); }","preventionTips":["One run() per wrapper instance","Close and rebuild the wrapper for re-election","Guard startLeaderElector against concurrent invocation"],"tags":["lifecycle","illegal-state","leader-election","kubernetes"],"backgroundTag":"invalid-state-transition","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"}