apache/druid · error · RE

Failed to get dependencies for extension

Error message

Failed to get dependencies for extension [%s]

What it means

getDruidExtensionDependencies() opens each jar in an extension directory to look for druid-extension-dependencies.json. If reading a jar throws IOException, it is wrapped in this RE, meaning the extension's dependencies could not be determined and the extension cannot be classloaded properly.

Solutions

  1. Validate each jar with `unzip -t <jar>` and re-download/replace corrupt ones
  2. Fix file permissions so the Druid process user can read the jars
  3. Remove broken jars from the extension directory
  4. Verify the extensions directory storage (NFS/disk) is healthy and fully synced

Example fix

// before
cp myext.jar extensions/myext/  # interrupted copy
// after
rsync --checksum myext.jar extensions/myext/ && unzip -t extensions/myext/myext.jar
Defensive patterns

Strategy: try-catch

Validate before calling

for (File jar : extDir.listFiles((d,n)->n.endsWith(".jar"))) {
  try (JarFile jf = new JarFile(jar)) { /* validate */ }
  catch (IOException e) { throw new IllegalStateException("Corrupt/unreadable jar: " + jar, e); }
}

Try / catch

try { loadExtension(ext); } catch (RE e) {
  if (e.getCause() instanceof IOException) { revalidateOrReinstallJars(extDir); }
  throw e;
}

Prevention

When it happens

Trigger: A jar in the extension directory is corrupt, truncated, unreadable (permissions), or deleted mid-scan, causing JarFile iteration to throw IOException during the dependency scan.

Common situations: Partially downloaded/copied extension jars (truncated uploads); jars owned by another user with restrictive permissions; corrupted jars on a bad disk or NFS mount; fat jars that are not valid zips.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/3cbe94c90ad094e6. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/guice/ExtensionsLoader.java:407

              throw new RE(
                  StringUtils.format(
                      "The extension [%s] has multiple jars [%s] [%s] with dependencies in them. Each jar should be in a separate extension directory.",
                      extension.getName(),
                      druidExtensionDependenciesJarName,
                      jarFile.getName()
                  )
              );
            }
            druidExtensionDependencies = objectMapper.readValue(
                jarFile.getInputStream(entry),
                DruidExtensionDependencies.class
            );
            druidExtensionDependenciesJarName = jarFile.getName();
          }
        }
      }
      catch (IOException e) {
        throw new RE(e, "Failed to get dependencies for extension [%s]", extension);
      }
    }
    return druidExtensionDependencies == null ? Optional.empty() : Optional.of(druidExtensionDependencies);
  }

  private class ServiceLoadingFromExtensions<T>
  {
    private final boolean isEmbeddedTest;
    private final Class<T> serviceClass;
    private final List<T> implsToLoad = new ArrayList<>();
    private final Set<String> implClassNamesToLoad = new HashSet<>();

    private ServiceLoadingFromExtensions(Class<T> serviceClass)
    {
      this.isEmbeddedTest = extensionsConfig.getModulesForEmbeddedTest() != null;
      if (isEmbeddedTest) {
        log.warn(
            "Running service in embedded testing mode with allowed modules[%s]."

View on GitHub (pinned to 9b90983fd2)