{"record":{"id":"98521239501efa56","repo":"apache/druid","slug":"log4j-shutdown-was-registered-in-lifecycle-but-no","errorCode":null,"errorMessage":"Log4j shutdown was registered in lifecycle but no shutdown object exists!","messagePattern":"Log4j shutdown was registered in lifecycle but no shutdown object exists!","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/src/main/java/org/apache/druid/initialization/Log4jShutterDownerModule.java","lineNumber":118,"sourceCode":"    public Log4jShutterDowner(Log4jShutdown log4jShutdown)\n    {\n      this.log4jShutdown = log4jShutdown;\n    }\n\n    @LifecycleStart\n    public void start()\n    {\n      log.debug(\"Log4j shutter downer is waiting\");\n    }\n\n    @LifecycleStop\n    public void stop()\n    {\n      if (log4jShutdown != null) {\n        log.debug(\"Shutting down log4j\");\n        log4jShutdown.stop();\n      } else {\n        log.warn(\"Log4j shutdown was registered in lifecycle but no shutdown object exists!\");\n      }\n    }\n  }\n}\n","sourceCodeStart":100,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/initialization/Log4jShutterDownerModule.java#L100-L123","documentation":"Log4jShutterDowner.stop() is invoked by the Druid lifecycle on shutdown. It warns when it was registered in the lifecycle but the injected Log4jShutdown instance is null, meaning shutdown logging hooks cannot be flushed. This usually indicates the module's conditional registration and the lifecycle provisioning got out of sync (e.g. a subclassed/overridden binding).","triggerScenarios":"Lifecycle stop() runs with log4jShutdown == null — the Guice binding for Log4jShutdown was not installed (earlier warning path) yet the shutdowner was still provided, or a custom module cleared the binding.","commonSituations":"Mixed-jar deployments where Log4jShutterDowner is bound eagerly but Log4jShutdown binding was skipped due to class loading issues; custom extension overriding the logging module bindings.","solutions":["Ensure the standard Log4jShutterDownerModule bindings are intact and no custom module rebinds Log4jShutterDowner without Log4jShutdown","Check startup logs for the earlier 'Not registering log4j shutdown hooks' warning and fix the underlying log4j classpath problem","Verify no duplicate Guice modules cause the eager singleton to be created from a different injector stage"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if (logManager.getFactory() instanceof Log4jContextFactory) { /* ok */ } else { skip registration; }","typeGuard":"boolean shutdownObjectBound(Injector injector) { try { injector.getInstance(Log4jShutdown.class); return true; } catch (ConfigurationException e) { return false; } }","tryCatchPattern":"try { lifecycle.stop(); } catch (IllegalStateException e) { LOG.warn(\"Log4j shutdown object missing; flushing appenders manually\", e); LogManager.shutdown(); }","preventionTips":["Don't override Log4jShutterDownerModule bindings with custom modules","Keep module registration and lifecycle registration in the same code path","Grep startup logs for the earlier skip warnings; they precede this failure"],"tags":["logging","log4j","guice","lifecycle"],"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"}