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

  1. Open the hivemq-extension.xml in the offending extension directory and ensure it contains an <id>some-id</id> element.
  2. Verify you are pointing at the actual extension directory (the one containing hivemq-extension.xml), not a parent or resource root.
  3. Rebuild the extension with the HiveMQ SDK so the descriptor is generated correctly.
  4. 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

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


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)