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

  1. Add the missing dependency extension to the extensions directory
  2. Include the dependency in druid.extensions.loadList so it is loaded
  3. Fix the druid.extension.dependencies entry in the extension's druid-extension-dependencies.json if it names a nonexistent extension
  4. 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

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


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)