{"record":{"id":"0fafa4fd788db4a3","repo":"apache/druid","slug":"can-t-stop-0fafa4","errorCode":null,"errorMessage":"can't stop.","messagePattern":"can't stop\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authentication/db/cache/CoordinatorPollingBasicAuthenticatorCacheManager.java","lineNumber":150,"sourceCode":"            catch (Throwable t) {\n              LOG.makeAlert(t, \"Error occurred while polling for cachedUserMaps.\").emit();\n            }\n          }\n      );\n\n      lifecycleLock.started();\n      LOG.info(\"Started CoordinatorPollingBasicAuthenticatorCacheManager.\");\n    }\n    finally {\n      lifecycleLock.exitStart();\n    }\n  }\n\n  @LifecycleStop\n  public void stop()\n  {\n    if (!lifecycleLock.canStop()) {\n      throw new ISE(\"can't stop.\");\n    }\n\n    LOG.info(\"CoordinatorPollingBasicAuthenticatorCacheManager is stopping.\");\n    exec.shutdownNow();\n    LOG.info(\"CoordinatorPollingBasicAuthenticatorCacheManager is stopped.\");\n  }\n\n  @Override\n  public void handleAuthenticatorUserMapUpdate(String authenticatorPrefix, byte[] serializedUserMap)\n  {\n    LOG.debug(\"Received user cache update for authenticator [%s].\", authenticatorPrefix);\n    Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS));\n    try {\n      cachedUserMaps.put(\n          authenticatorPrefix,\n          objectMapper.readValue(\n              serializedUserMap,\n              BasicAuthUtils.AUTHENTICATOR_USER_MAP_TYPE_REFERENCE","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authentication/db/cache/CoordinatorPollingBasicAuthenticatorCacheManager.java#L132-L168","documentation":"Thrown by CoordinatorPollingBasicAuthenticatorCacheManager.stop when lifecycleLock.canStop() returns false. stop() may only be called when the component is actually in a started state; calling stop before start, twice in a row, or concurrently fails this guard with an ISE. It signals an illegal lifecycle transition, not a shutdown problem per se.","triggerScenarios":"stop() called before start(); stop() called twice; concurrent stop from two threads after the first already claimed the transition; failing to await completion of a prior stop lifecycle stage.","commonSituations":"Test code (e.g. test_stop_interruptsPollingThread) invoking stop out of order; shutdown hooks firing after an earlier stop; leadership loss handling that stops twice.","solutions":["Ensure stop() is only called after a successful start() on the same instance","Make stop idempotent by tracking stopped state in the caller or fixing the lifecycle lock usage","In tests, always start before stopping and stop once per lifecycle","Wrap shutdown logic so it checks lifecycle state rather than assuming the manager is running"],"exampleFix":"// before\nmanager.stop(); manager.stop(); // second call throws\n// after\nif (running) { manager.stop(); running = false; }","handlingStrategy":"try-catch","validationCode":"boolean stopIfRunning(AtomicBoolean running, CoordinatorPollingBasicAuthenticatorCacheManager m) { if (!running.get()) return false; m.stop(); running.set(false); return true; }","typeGuard":null,"tryCatchPattern":"try { manager.stop(); } catch (ISE e) { LOG.info(\"stop ignored: manager not in started state\"); }","preventionTips":["Pair every start() with exactly one stop()","Never stop before a successful start()","Use an AtomicBoolean to make stop idempotent at the call site","Ensure shutdown hooks don't double-invoke lifecycle stop"],"tags":["lifecycle","illegal-state","shutdown"],"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"}