apache/druid · error · ISE
Root extensions directory [%s] is not a directory!?
Error message
Root extensions directory [%s] is not a directory!?
What it means
ExtensionsLoader.initializeExtensionFilesToLoad() validates the druid.extensions.directory path. This ISE is thrown when the configured root extensions path exists on disk but is a regular file (or other non-directory), so extensions cannot be listed underneath it.
Source
Thrown at processing/src/main/java/org/apache/druid/guice/ExtensionsLoader.java:189
return getFromExtensions(DruidModule.class);
}
/**
* Find all the extension files that should be loaded by druid.
* <p/>
* If user explicitly specifies druid.extensions.loadList, then it will look for those extensions under root
* extensions directory. If one of them is not found, druid will fail loudly.
* <p/>
* If user doesn't specify druid.extension.toLoad (or its value is empty), druid will load all the extensions
* under the root extensions directory.
*
* @return an array of druid extension files that will be loaded by druid process
*/
public void initializeExtensionFilesToLoad()
{
final File rootExtensionsDir = new File(extensionsConfig.getDirectory());
if (rootExtensionsDir.exists() && !rootExtensionsDir.isDirectory()) {
throw new ISE("Root extensions directory [%s] is not a directory!?", rootExtensionsDir);
}
File[] extensionsToLoad;
final LinkedHashSet<String> toLoad = extensionsConfig.getLoadList();
if (toLoad == null) {
extensionsToLoad = rootExtensionsDir.listFiles();
} else {
final LinkedHashSet<String> validExtensionsToLoad = new LinkedHashSet<>(toLoad);
if (validExtensionsToLoad.remove("druid-multi-stage-query")) {
log.warn(
"Skipping extension[druid-multi-stage-query] as it is now a core"
+ " capability of Druid. Please remove this extension from your"
+ " configs as it will cause services to fail in future Druid versions."
);
}
int i = 0;
extensionsToLoad = new File[validExtensionsToLoad.size()];
for (final String extensionName : validExtensionsToLoad) {View on GitHub (pinned to 9b90983fd2)
Solutions
- Check the path with `ls -ld <path>`; it must be a directory
- Fix druid.extensions.directory to point to the extensions directory (default: extensions/)
- Create the directory if it was intended but missing: `mkdir -p <path>` (a missing path is tolerated; only an existing non-directory fails)
- If pointing at a symlink, ensure the symlink resolves to a directory
Example fix
// before (runtime config) druid.extensions.directory=/opt/druid/extensions.zip // after druid.extensions.directory=/opt/druid/extensions
Defensive patterns
Strategy: validation
Validate before calling
File dir = new File(extensionsDir);
if (dir.exists() && !dir.isDirectory()) {
throw new IllegalStateException("druid.extensions.directory must be a directory: " + dir);
} Try / catch
try { startDruid(); } catch (ISE e) {
if (e.getMessage().contains("is not a directory")) { fixExtensionsDirConfig(); }
throw e;
} Prevention
- Validate druid.extensions.directory in startup scripts before launching Druid
- Never point the setting at archives or individual jars
- After host migrations, verify the path resolves to a real directory
When it happens
Trigger: Starting any Druid process with druid.extensions.directory set to a path that exists but is not a directory (e.g. pointing at a jar file or a symlink to a file).
Common situations: Misconfigured extensions dir after copying configs between hosts; accidentally pointing druid.extensions.directory at a tarball or single file; a mount point replaced by a file.
Related errors
- taskLogDir [%s] must be a directory.
- Extension [%s] specified in "druid.extensions.loadList" didn
- Unknown provider [%s] of %s, known options [%s]
- Unable to create storage connector [%s] for base path [%s]
- The gRPC query server requires either a Basic or Anonymous a
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/3822a3aa2d838a4c.
Report an issue: GitHub.