testcontainers/testcontainers-java · warning

Version is not a semantic version, LocalStack will run in…

Error message

Version {} is not a semantic version, LocalStack will run in legacy mode.

What it means

shouldRunInLegacyMode compares the LocalStack image version to 0.11 to decide between the legacy single-container setup and the modern one. When the version tag is not a semantic version, the method logs this warning (plus the follow-up constructor hint) and returns true, forcing legacy mode. Users with non-standard image tags get legacy behavior they may not expect.

Solutions

  1. Pin a semantic version tag such as localstack/localstack:2.3.0
  2. Use the explicit constructor new LocalStackContainer(image, false) to opt out of legacy mode regardless of tag parsing
  3. Set up withServices() explicitly so the container config is intentional

Example fix

// before
new LocalStackContainer(DockerImageName.parse("localstack/localstack:nightly"))
// after
new LocalStackContainer(DockerImageName.parse("localstack/localstack:2.3.0"), false)
Defensive patterns

Strategy: validation

Validate before calling

String tag = imageName.getVersionPart();
if (!tag.matches("\\d+(\\.\\d+)*")) {
    // choose mode explicitly rather than letting the fallback decide
}
new LocalStackContainer(imageName, /*legacyMode*/ false);

Prevention

When it happens

Trigger: Creating LocalStackContainer with an image tag that cannot be parsed as a semantic version (e.g. :latest, :nightly, custom tags); the static shouldRunInLegacyMode(version) check falls into the non-semantic branch.

Common situations: CI caching 'latest' of localstack; local builds tagged 'local'; older testcontainers code paths that accepted arbitrary image names.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12). Data as JSON: /api/errors/0de177dd9dfdcae2. Report an issue: GitHub.

Appendix: source

Thrown at modules/localstack/src/main/java/org/testcontainers/containers/localstack/LocalStackContainer.java:175

        log.warn("Version {} is not a semantic version, services list is required.", version);

        return true;
    }

    static boolean shouldRunInLegacyMode(String version) {
        // assume that the latest images are up-to-date
        // also consider images with extra packages (like latest-bigdata) and service-specific images (like s3-latest)
        if (version.equals("latest") || version.startsWith("latest-") || version.endsWith("-latest")) {
            return false;
        }

        ComparableVersion comparableVersion = new ComparableVersion(version);
        if (comparableVersion.isSemanticVersion()) {
            boolean versionRequiresLegacyMode = comparableVersion.isLessThan("0.11");
            return versionRequiresLegacyMode;
        }

        log.warn("Version {} is not a semantic version, LocalStack will run in legacy mode.", version);
        log.warn(
            "Consider using \"LocalStackContainer(DockerImageName dockerImageName, boolean legacyMode)\" constructor if you want to disable legacy mode."
        );
        return true;
    }

    @Override
    protected void configure() {
        super.configure();

        if (this.servicesEnvVarRequired) {
            Preconditions.check("services list must not be empty", !services.isEmpty());
        }

        if (!services.isEmpty()) {
            withEnv("SERVICES", services.stream().map(EnabledService::getName).collect(Collectors.joining(",")));
            if (this.servicesEnvVarRequired) {
                withEnv("EAGER_SERVICE_LOADING", "1");

View on GitHub (pinned to 8e549514e3)