apache/druid · warning
Shutdown callback registry expected class
Error message
Shutdown callback registry expected class [%s] found [%s]. Skipping shutdown registry
What it means
After confirming a Log4jContextFactory, the module asks it for its ShutdownCallbackRegistry and requires it to be Druid's Log4jShutdown class to hook lifecycle-managed shutdown. If log4j was configured with a custom shutdownCallbackRegistry, the default registry type is returned instead, so Druid skips installing its shutdown hooks and warns.
Solutions
- Remove any log4j2.shutdownCallbackRegistry / log4j.shutdownCallbackRegistry property from log4j2.component.properties or system properties so log4j uses Druid's Log4jShutdown
- Check the classpath for duplicate log4j-core jars that may carry a different default registry
- Align Druid server module and extension versions so the Log4jShutdown class matches the one log4j loads
Example fix
// before: log4j2.component.properties log4j.shutdownCallbackRegistry=com.example.MyShutdownRegistry // after (property removed, letting Druid's Log4jShutdown be the registry)
Defensive patterns
Strategy: validation
Validate before calling
final String reg = System.getProperty("log4j.shutdownCallbackRegistry", System.getenv("LOG4J_SHUTDOWN_CALLBACK_REGISTRY") != null ? System.getenv("LOG4J_SHUTDOWN_CALLBACK_REGISTRY") : "org.apache.druid.server.logging.Log4jShutdown"); boolean ok = reg.endsWith("Log4jShutdown"); Prevention
- Never set log4j.shutdownCallbackRegistry in log4j2.component.properties for Druid
- Keep log4j-core at the version Druid expects
- Diff log4j2.component.properties against the stock Druid config after upgrades
When it happens
Trigger: configure() calls ((Log4jContextFactory) contextFactory).getShutdownCallbackRegistry() and the registry is not a Log4jShutdown — caused by setting the log4j2 system property log4j.shutdownCallbackRegistry to a custom registry class, or bundling a library that overrides it.
Common situations: Custom log4j2.component.properties shipping ShutdownCallbackRegistry overrides; shaded jars embedding their own registry; mixing Druid versions whose Log4jShutdown differs from the one log4j instantiates.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Expected [ ] found [ ]. Unknown class for context factory…
- Log4j shutdown was registered in lifecycle but no shutdown…
- Not registering log4j shutdown hooks. Not using log4j?
- A valid tlsPort needs to specified when druid.enableTlsPort…
- Already shut down, not starting again
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/7113d7bf0e4d75f0.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/main/java/org/apache/druid/initialization/Log4jShutterDownerModule.java:69
}
// Reflection to try and allow non Log4j2 stuff to run. This acts as a gateway to stop errors in the next few lines
// In log4j api
Class.forName("org.apache.logging.log4j.LogManager", false, loader);
// In log4j core
Class.forName("org.apache.logging.log4j.core.util.ShutdownCallbackRegistry", false, loader);
final LoggerContextFactory contextFactory = LogManager.getFactory();
if (!(contextFactory instanceof Log4jContextFactory)) {
log.warn(
"Expected [%s] found [%s]. Unknown class for context factory. Not logging shutdown",
Log4jContextFactory.class.getName(),
contextFactory.getClass().getName()
);
return;
}
final ShutdownCallbackRegistry registry = ((Log4jContextFactory) contextFactory).getShutdownCallbackRegistry();
if (!(registry instanceof Log4jShutdown)) {
log.warn(
"Shutdown callback registry expected class [%s] found [%s]. Skipping shutdown registry",
Log4jShutdown.class.getName(),
registry.getClass().getName()
);
return;
}
binder.bind(Log4jShutdown.class).toInstance((Log4jShutdown) registry);
binder.bind(Key.get(Log4jShutterDowner.class, Names.named("ForTheEagerness")))
.to(Log4jShutterDowner.class)
.asEagerSingleton();
}
catch (ClassNotFoundException | ClassCastException | LinkageError e) {
log.warn(e, "Not registering log4j shutdown hooks. Not using log4j?");
}
}
@ManageLifecycleInitView on GitHub (pinned to 9b90983fd2)