testcontainers/testcontainers-java · error · ContainerLaunchException
Extension ' ' could not be mounted. It is not a directory.
Error message
Extension '{path}' could not be mounted. It is not a directory. What it means
After checking existence, the MountableFile-based withExtension validates that the resolved path is a directory, because HiveMQ extensions are mounted as folders under /opt/hivemq/temp-extensions/. Mounting a plain file would produce a broken extension, so the library throws this ContainerLaunchException.
Solutions
- Pass the extension directory (the folder containing hivemq-extension.xml), not a file inside it.
- Unpack any zipped extension to a directory first, then wrap the directory with MountableFile.forHostPath(dir).
- Check the resolved path with File.isDirectory() in a debugger/print to confirm what you are passing.
Example fix
// before
withExtension(MountableFile.forHostPath("ext/my-extension.zip")); // a file
// after
File dir = unzipTo(new File("ext/my-extension.zip"), tempDir);
withExtension(MountableFile.forHostPath(dir)); // directory containing hivemq-extension.xml Defensive patterns
Strategy: validation
Validate before calling
File dir = new File(mountableFile.getResolvedPath());
if (!dir.isDirectory()) {
throw new IllegalArgumentException("Expected an extension directory, got: " + dir);
} Prevention
- Always pass the directory containing hivemq-extension.xml, never an archive or inner file.
- Unzip extensions before mounting.
- Name variables clearly (extensionDir vs extensionZip) to avoid mix-ups.
When it happens
Trigger: Passing a MountableFile that resolves to a regular file (e.g. a .zip or a single hivemq-extension.xml) instead of the extension's directory.
Common situations: Pointing at an archive or a single descriptor file instead of the unpacked extension folder; a symlink that resolves to a file; mixing up the extension jar path with the extension directory.
Related errors
- Extension ' ' could not be mounted. It does not exist.
- Could not parse extension id from
- License file ' ' does not exist.
- HiveMQ config file ' ' does not exist.
- pathInHomeFolder must not be empty
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/737652b0757613fe.
Report an issue: GitHub.
Appendix: source
Thrown at modules/hivemq/src/main/java/org/testcontainers/hivemq/HiveMQContainer.java:251
* It must at least contain a valid hivemq-extension.xml and a valid extension.jar in order to be executed.
* The directory-name is taken from the id defined in the hivemq-extension.xml.
* <p>
* Must be called before the container is started.
* <p>
* The contents of the '/opt/hivemq/temp-extensions/' directory are copied to '/opt/hivemq/extensions/' before the container is started.
*
* @param mountableExtension the extension folder on the host machine
* @return self
*/
public @NotNull HiveMQContainer withExtension(final @NotNull MountableFile mountableExtension) {
final File extensionDir = new File(mountableExtension.getResolvedPath());
if (!extensionDir.exists()) {
throw new ContainerLaunchException(
"Extension '" + mountableExtension.getFilesystemPath() + "' could not be mounted. It does not exist."
);
}
if (!extensionDir.isDirectory()) {
throw new ContainerLaunchException(
"Extension '" +
mountableExtension.getFilesystemPath() +
"' could not be mounted. It is not a directory."
);
}
try {
final String extensionDirName = getExtensionDirectoryName(extensionDir);
final String containerPath = "/opt/hivemq/temp-extensions/" + extensionDirName;
withCopyFileToContainer(cloneWithFileMode(mountableExtension), containerPath);
LOGGER.info("Putting extension '{}' into '{}'", extensionDirName, containerPath);
} catch (final Exception e) {
throw new ContainerLaunchException(e.getMessage() == null ? "" : e.getMessage(), e);
}
return self();
}
private @NotNull String getExtensionDirectoryName(final @NotNull File extensionDirectory) throws IOException {
final File file = new File(extensionDirectory, "hivemq-extension.xml");View on GitHub (pinned to 8e549514e3)