testcontainers/testcontainers-java · error · IllegalStateException
Could not parse extension id from
Error message
Could not parse extension id from '{fileAbsolutePath}' What it means
getExtensionDirectoryName reads the hivemq-extension.xml descriptor inside an extension directory and extracts the extension id with the EXTENSION_ID_PATTERN regex. If the XML file exists but contains no recognizable <id> element, the library cannot determine the extension's identity and throws IllegalStateException. This is effectively a malformed or unexpected extension descriptor.
Solutions
- Open the hivemq-extension.xml in the offending extension directory and ensure it contains an <id>some-id</id> element.
- Verify you are pointing at the actual extension directory (the one containing hivemq-extension.xml), not a parent or resource root.
- Rebuild the extension with the HiveMQ SDK so the descriptor is generated correctly.
- If prepackaged HiveMQ extensions are involved, ensure they were extracted fully and not partially copied.
Example fix
// before
// extensions dir contains hivemq-extension.xml without <id>
// after
<hivemq-extension>
<id>my-extension</id>
<name>My Extension</name>
<version>1.0.0</version>
</hivemq-extension> Defensive patterns
Strategy: validation
Validate before calling
File xml = new File(extDir, "hivemq-extension.xml");
String content = Files.readString(xml.toPath());
if (!content.contains("<id>")) throw new IllegalStateException("hivemq-extension.xml missing <id> in " + extDir); Try / catch
try { container.enableExtension(id); } catch (IllegalStateException e) { /* inspect hivemq-extension.xml */ } Prevention
- Always generate the extension with the HiveMQ SDK so hivemq-extension.xml includes <id>.
- Sanity-check mounted extension directories contain a well-formed descriptor before starting the container.
When it happens
Trigger: Called from extensionDirName when a directory mounted/copied under /opt/hivemq/extensions contains a hivemq-extension.xml that does not match EXTENSION_ID_PATTERN (e.g. missing <id> tag, differently formatted XML, empty file, or a non-HiveMQ extension layout).
Common situations: Mounting a custom or hand-written extension folder into the container; a build tool (Gradle/Maven shadow packaging) producing an extension XML without the id element; HiveMQ SDK version change altering the descriptor schema; pointing at a directory that has an unrelated or placeholder hivemq-extension.xml.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Extension ' ' could not be mounted. It does not exist.
- Extension ' ' could not be mounted. It is not a directory.
- 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/4d75b891038ddc89.
Report an issue: GitHub.
Appendix: source
Thrown at modules/hivemq/src/main/java/org/testcontainers/hivemq/HiveMQContainer.java:274
}
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");
final String xml = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
final Matcher matcher = EXTENSION_ID_PATTERN.matcher(xml);
if (!matcher.find()) {
throw new IllegalStateException("Could not parse extension id from '" + file.getAbsolutePath() + "'");
}
return matcher.group(1);
}
/**
* Removes the specified prepackaged extension folders from '/opt/hivemq/extensions' before the container is started.
* <p>
* Must be called before the container is started.
*
* @param extensionIds the prepackaged extensions to remove
* @return self
*/
public @NotNull HiveMQContainer withoutPrepackagedExtensions(final @NotNull String... extensionIds) {
Collections.addAll(prepackagedExtensionsToRemove, extensionIds);
return self();
}
/**View on GitHub (pinned to 8e549514e3)