testcontainers/testcontainers-java · error · java.lang.IllegalStateException

Cannot determine HTTP scheme: environment variables are not…

Error message

Cannot determine HTTP scheme: environment variables are not set and container is not running for curl probe

What it means

ElasticsearchContainer.getHttpScheme determines whether to use http or https: it first checks the ELASTIC_PASSWORD/xpack.security.enabled env vars, then httpSslEnabled; if neither is set it probes the container via curl — but only when the container is running. If no env configuration exists and the container is not running, it throws IllegalStateException because the curl probe cannot be executed.

Solutions

  1. Start the container before calling url()/getHttpHost() — derive endpoints lazily in the test body or an @Before callback.
  2. Set the scheme explicitly by configuring security env (e.g. withPassword or withEnabledFlags/withEnv("xpack.security.enabled","false")) so no runtime probe is needed.
  3. If you must precompute URLs, run the container as a static/singleton started before endpoint resolution.

Example fix

// before
String url = container.getHttpHostAddress(); // before start, no env set -> throws
container.start();
// after
container.start();
String url = container.getHttpHostAddress();
Defensive patterns

Strategy: validation

Validate before calling

if (!container.isRunning()) {
    throw new IllegalStateException("Call url()/getHttpHostAddress() only after container.start()");
}
String host = container.getHttpHostAddress();

Try / catch

try {
    String address = container.getHttpHostAddress();
} catch (IllegalStateException e) {
    if (e.getMessage().contains("Cannot determine HTTP scheme")) {
        // container not started and no security env configured
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling url(), getHttpHost(), or scheme-related accessors before start() on a container created without ELASTIC_PASSWORD, xpack.security.enabled, or withEnabledFlags/withSsl env configuration.

Common situations: Building the client URL at field-initialization time before the container starts; computing the endpoint in a config class instantiated before container startup.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/ElasticsearchContainer.java:291

     * Detects the HTTP scheme used by Elasticsearch. Respects explicit env-var config first;
     * when ambiguous, probes the live socket with curl (requires a running container on port 9200).
     *
     * @return "http" or "https"
     */
    String getHttpScheme() {
        String securityEnabled = getEnvMap().get("xpack.security.enabled");
        String httpSslEnabled = getEnvMap().get("xpack.security.http.ssl.enabled");

        // Respect explicit user config
        if ("false".equalsIgnoreCase(securityEnabled) || "false".equalsIgnoreCase(httpSslEnabled)) {
            return "http";
        }
        if ("true".equalsIgnoreCase(httpSslEnabled)) {
            return "https";
        }

        if (!isRunning()) {
            throw new IllegalStateException(
                "Cannot determine HTTP scheme: environment variables are not set and container is not running for curl probe"
            );
        }

        ExecResult httpsResult = null;
        ExecResult httpResult = null;
        try {
            // HTTPS probe: any HTTP response (200/401/403/...) => scheme is HTTPS.
            // http_code == 000 means we didn't get an HTTP response (TLS/connect failure/timeout).
            httpsResult =
                execInContainer(
                    "curl",
                    "-sS",
                    "-k",
                    "--connect-timeout",
                    "2",
                    "--max-time",
                    "4",

View on GitHub (pinned to 8e549514e3)