{"record":{"id":"006a26da68737a23","repo":"apache/druid","slug":"can-t-start-006a26","errorCode":null,"errorMessage":"can't start.","messagePattern":"can't start\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/query/lookup/LookupReferencesManager.java","lineNumber":152,"sourceCode":"      this.lookupSnapshotTaker = null;\n    } else {\n      this.lookupSnapshotTaker = new LookupSnapshotTaker(objectMapper, lookupConfig.getSnapshotWorkingDir());\n    }\n    this.coordinatorClient = coordinatorClient;\n    this.lookupListeningAnnouncerConfig = lookupListeningAnnouncerConfig;\n    this.lookupConfig = lookupConfig;\n    this.testMode = testMode;\n    this.lookupUpdateExecutorService = Execs.multiThreaded(\n        lookupConfig.getNumLookupLoadingThreads(),\n        \"LookupExtractorFactoryContainerProvider-Update-%s\"\n    );\n  }\n\n  @LifecycleStart\n  public void start() throws IOException\n  {\n    if (!lifecycleLock.canStart()) {\n      throw new ISE(\"can't start.\");\n    }\n    try {\n      LOG.debug(\"LookupExtractorFactoryContainerProvider starting.\");\n      if (!Strings.isNullOrEmpty(lookupConfig.getSnapshotWorkingDir())) {\n        FileUtils.mkdirp(new File(lookupConfig.getSnapshotWorkingDir()));\n      }\n      loadLookupsAndInitStateRef();\n      if (!testMode) {\n        mainThread = Execs.makeThread(\n            \"LookupExtractorFactoryContainerProvider-MainThread\",\n            () -> {\n              try {\n                if (!lifecycleLock.awaitStarted()) {\n                  LOG.error(\"Lifecycle not started, lookup update notices will not be handled.\");\n                  return;\n                }\n\n                while (!Thread.interrupted() && lifecycleLock.awaitStarted(1, TimeUnit.MILLISECONDS)) {","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/query/lookup/LookupReferencesManager.java#L134-L170","documentation":"LookupReferencesManager.start(), annotated @LifecycleStart, uses a LifecycleLock; if canStart() returns false (already started, stop in progress, or stop already completed), it throws IllegalStateException 'can't start.' This enforces that the lookup manager transitions through its lifecycle exactly once and in order.","triggerScenarios":"Calling start() after the manager is already started; calling start() concurrently with or after stop(); lifecycle mis-wiring where a second component attempts to start the same instance.","commonSituations":"Double registration of LookupReferencesManager in a custom lifecycle; unit tests starting/stopping repeatedly without resetting; race between node shutdown and startup hooks.","solutions":["Ensure start() is called exactly once per LookupReferencesManager instance via the Druid Lifecycle.","Check logs/stack trace for a prior stop() call that invalidated the lifecycle lock.","In tests, construct a fresh LookupReferencesManager per lifecycle cycle rather than reusing instances.","Avoid calling start() from multiple threads; delegate to a single lifecycle coordinator."],"exampleFix":"// before\nmanager.stop();\nmanager.start(); // ISE: can't start.\n// after\nLookupReferencesManager manager = new LookupReferencesManager(...); // fresh instance\nmanager.start();","handlingStrategy":"validation","validationCode":"// call start() exactly once, e.g.\nprivate final AtomicBoolean started = new AtomicBoolean(false);\nif (started.compareAndSet(false, true)) { manager.start(); }","typeGuard":null,"tryCatchPattern":"try {\n  manager.start();\n} catch (IllegalStateException e) {\n  // already started or stopped: treat as idempotent no-op or recreate instance\n}","preventionTips":["Let the Druid Lifecycle own start/stop; avoid manual calls","Never call start() after stop() on the same instance","Use a fresh instance per test lifecycle cycle"],"tags":["lifecycle","lookup","state"],"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-14T11:17:12.474Z"}