{"record":{"id":"861f93edb3d397c0","repo":"apache/druid","slug":"expected-s-found-s-unknown-class-for-contex","errorCode":null,"errorMessage":"Expected [%s] found [%s]. Unknown class for context factory. Not logging shutdown","messagePattern":"Expected \\[(.+?)\\] found \\[(.+?)\\]\\. Unknown class for context factory\\. Not logging shutdown","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/src/main/java/org/apache/druid/initialization/Log4jShutterDownerModule.java","lineNumber":60,"sourceCode":"  public void configure(Binder binder)\n  {\n    // Instantiate eagerly so that we get everything registered and put into the Lifecycle as early as possible\n    // Lifecycle scope is INIT to ensure stop runs in the last phase of lifecycle stop.\n\n    try {\n      ClassLoader loader = Thread.currentThread().getContextClassLoader();\n      if (loader == null) {\n        loader = getClass().getClassLoader();\n      }\n      // Reflection to try and allow non Log4j2 stuff to run. This acts as a gateway to stop errors in the next few lines\n      // In log4j api\n      Class.forName(\"org.apache.logging.log4j.LogManager\", false, loader);\n      // In log4j core\n      Class.forName(\"org.apache.logging.log4j.core.util.ShutdownCallbackRegistry\", false, loader);\n\n      final LoggerContextFactory contextFactory = LogManager.getFactory();\n      if (!(contextFactory instanceof Log4jContextFactory)) {\n        log.warn(\n            \"Expected [%s] found [%s]. Unknown class for context factory. Not logging shutdown\",\n            Log4jContextFactory.class.getName(),\n            contextFactory.getClass().getName()\n        );\n        return;\n      }\n      final ShutdownCallbackRegistry registry = ((Log4jContextFactory) contextFactory).getShutdownCallbackRegistry();\n      if (!(registry instanceof Log4jShutdown)) {\n        log.warn(\n            \"Shutdown callback registry expected class [%s] found [%s]. Skipping shutdown registry\",\n            Log4jShutdown.class.getName(),\n            registry.getClass().getName()\n        );\n        return;\n      }\n      binder.bind(Log4jShutdown.class).toInstance((Log4jShutdown) registry);\n      binder.bind(Key.get(Log4jShutterDowner.class, Names.named(\"ForTheEagerness\")))\n            .to(Log4jShutterDowner.class)","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/initialization/Log4jShutterDownerModule.java#L42-L78","documentation":"Log4jShutterDownerModule registers a graceful log4j shutdown hook during Guice configuration. If the installed SLF4J/log4j binding provides a LoggerContextFactory that is not Log4jContextFactory, the module cannot install the shutdown registry and warns that shutdown logging will be skipped. This is a guard against running under an unexpected or custom log4j provider.","triggerScenarios":"Guice configure() runs at startup while LogManager.getFactory() returns a factory that is not an instance of org.apache.logging.log4j.core.impl.Log4jContextFactory — e.g. a custom or third-party LoggerContextFactory, a stripped log4j-core jar, or a different provider (slf4j-simple, logback bridge) exposing log4j API.","commonSituations":"Deploying Druid with a custom logging setup, shading or excluding log4j-core, using a log4j-to-slf4j bridge, or accidentally including multiple logging bindings so a non-default factory wins.","solutions":["Ensure log4j-core is on the classpath and that no log4j-to-slf4j or other provider jar replaces the default Log4jContextFactory","Remove conflicting logging bindings (e.g. slf4j-log4j12, logback-classic) so log4j-slf4j-impl + log4j-core are used","If a custom LoggerContextFactory is intentional, accept the warning or patch the module to support it"],"exampleFix":"// before (pom.xml)\n<dependency>\n  <groupId>org.apache.logging.log4j</groupId>\n  <artifactId>log4j-to-slf4j</artifactId>\n</dependency>\n// after\n<dependency>\n  <groupId>org.apache.logging.log4j</groupId>\n  <artifactId>log4j-slf4j-impl</artifactId>\n</dependency>\n<dependency>\n  <groupId>org.apache.logging.log4j</groupId>\n  <artifactId>log4j-core</artifactId>\n</dependency>","handlingStrategy":"validation","validationCode":"Class.forName(\"org.apache.logging.log4j.core.impl.Log4jContextFactory\", false, getClass().getClassLoader());","typeGuard":"boolean isLog4jCoreOnClasspath() { try { Class.forName(\"org.apache.logging.log4j.core.impl.Log4jContextFactory\", false, Thread.currentThread().getContextClassLoader()); return true; } catch (ClassNotFoundException e) { return false; } }","tryCatchPattern":null,"preventionTips":["Ship log4j-slf4j-impl and log4j-core together in deployments","Audit runtime classpath for competing SLF4J providers","Check startup logs for logging-module warnings after any dependency change"],"tags":["logging","log4j","classpath","guice"],"backgroundTag":"missing-optional-dependency","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"}