apache/druid · error · RE
Extension [ ] depends on [ ] which is not a valid extension…
Error message
Extension [%s] depends on [%s] which is not a valid extension or not loaded.
What it means
Druid extensions can declare dependencies on other Druid extensions via druid.extension.dependencies in their dependencies JSON. getClassLoaderForExtension() builds a classloader chain, and this RE is thrown when a declared dependency's name does not match any extension directory currently slated for loading.
Solutions
- Add the missing dependency extension to the extensions directory
- Include the dependency in druid.extensions.loadList so it is loaded
- Fix the druid.extension.dependencies entry in the extension's druid-extension-dependencies.json if it names a nonexistent extension
- Remove the dependency declaration if the newer version of the extension no longer needs it
Example fix
// before -Ddruid.extensions.loadList="[\"druid-kerberos\"]" // after -Ddruid.extensions.loadList="[\"druid-kerberos\", \"druid-basic-security\"]"
Defensive patterns
Strategy: validation
Validate before calling
Set<String> loaded = new HashSet<>(loadList);
for (String dep : declaredDeps(extension)) {
if (!loaded.contains(dep)) {
throw new IllegalStateException(extension + " needs unloaded extension " + dep);
}
} Try / catch
try { getClassLoaderForExtension(ext); } catch (RE e) {
if (e.getMessage().contains("not a valid extension or not loaded")) { loadDependency(ext, e); }
throw e;
} Prevention
- Read each extension's druid-extension-dependencies.json and include all entries in loadList
- Keep companion extensions installed together as a bundle
- After removing an extension, grep other extensions' dependency manifests for it
When it happens
Trigger: Extension A's druid-extension-dependencies.json lists extension B in druid.extension.dependencies, but B is absent from the extensions directory or excluded from the loadList when getClassLoaderForExtension(A) is invoked.
Common situations: Installing an extension but forgetting its required companion extension; loadList omits a transitive dependency; upgrading one extension while its dependency was removed; typos in the dependencies JSON.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- Extension [ ] has a circular druid extension dependency…
- Extension [ ] specified in "druid.extensions.loadList"…
- Failed to find MariaDB driver class. Please check the…
- Failed to find MySQL driver class. Please check the MySQL…
- Failed to get dependencies for extension
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/e81f879137235ddd.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/guice/ExtensionsLoader.java:282
return classLoader;
}
}
private StandardURLClassLoader makeClassLoaderWithDruidExtensionDependencies(File extension, boolean useExtensionClassloaderFirst, List<String> extensionDependencyStack)
{
Optional<DruidExtensionDependencies> druidExtensionDependenciesOptional = getDruidExtensionDependencies(extension);
List<String> druidExtensionDependenciesList = druidExtensionDependenciesOptional.isPresent()
? druidExtensionDependenciesOptional.get().getDependsOnDruidExtensions()
: ImmutableList.of();
List<ClassLoader> extensionDependencyClassLoaders = new ArrayList<>();
for (String druidExtensionDependencyName : druidExtensionDependenciesList) {
Optional<File> extensionDependencyFileOptional = Arrays.stream(getExtensionFilesToLoad())
.filter(file -> file.getName().equals(druidExtensionDependencyName))
.findFirst();
if (!extensionDependencyFileOptional.isPresent()) {
throw new RE(
StringUtils.format(
"Extension [%s] depends on [%s] which is not a valid extension or not loaded.",
extension.getName(),
druidExtensionDependencyName
)
);
}
File extensionDependencyFile = extensionDependencyFileOptional.get();
if (extensionDependencyStack.contains(extensionDependencyFile.getName())) {
extensionDependencyStack.add(extensionDependencyFile.getName());
throw new RE(
StringUtils.format(
"Extension [%s] has a circular druid extension dependency. Dependency stack [%s].",
extensionDependencyStack.get(0),
extensionDependencyStack
)
);
}View on GitHub (pinned to 9b90983fd2)