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
- Start the container before calling url()/getHttpHost() — derive endpoints lazily in the test body or an @Before callback.
- Set the scheme explicitly by configuring security env (e.g. withPassword or withEnabledFlags/withEnv("xpack.security.enabled","false")) so no runtime probe is needed.
- 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
- Resolve container endpoints lazily, only after start().
- Configure security env vars explicitly (withPassword or xpack.security.enabled) so the scheme is known without a probe.
- Use static singleton containers when endpoints must be computed early in test setup.
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
- Elasticsearch containerId is not available. In managed…
- You should never close the global DockerClient!
- Setter can only be called before the container is running
- You can not activate security on Elastic OSS Image. Please…
- Failed to detect protocol via curl
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)