testcontainers/testcontainers-java · error · java.lang.RuntimeException
Failed to detect protocol via curl
Error message
Failed to detect protocol via curl
What it means
ElasticsearchContainer.getHttpScheme() probes the running container by executing curl (HTTPS then HTTP) against localhost:9200 inside the container to determine which scheme the node is serving. This RuntimeException wraps any exception thrown while executing those probes (e.g. container exec failure). A sibling error reports probe results when both probes complete but fail.
Solutions
- Ensure the container image contains a curl binary (testcontainers images include it; custom images may not).
- Wait for the container to be running/ready (waitingFor(Wait.forHttp(...))) before calling getHttpScheme().
- Check the wrapped cause (RuntimeException.getCause()) for the actual exec failure and fix the underlying Docker/container issue.
- Upgrade the Elasticsearch container image to an official Testcontainers-supported one.
Example fix
// before
String scheme = container.getHttpScheme(); // may throw
// after
if (container.isRunning()) {
String scheme = container.getHttpScheme();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!container.isRunning()) { throw new IllegalStateException("Container must be running before getHttpScheme()"); } Try / catch
try { String scheme = container.getHttpScheme(); } catch (RuntimeException e) { LOG.error("curl protocol probe failed; check image has curl and container is alive", e.getCause()); throw e; } Prevention
- Use official testcontainers Elasticsearch images that ship curl.
- Configure a wait strategy before querying the scheme.
- Never call getHttpScheme() after stopping the container.
- Log the cause chain — the wrapped exception explains the exec failure.
When it happens
Trigger: Calling getHttpScheme()/getHttpHostAddress()/url/scheme when execInContainer("curl", ...) throws — e.g. container stopped mid-probe, exec API failure, or curl missing from the image.
Common situations: Custom/minimal Elasticsearch images without curl installed; container stopped or paused by resource pressure between readiness checks and the probe; Docker engine issues during exec.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to detect protocol via curl. Both HTTPS and HTTP…
- withReuse(true) is not supported for KibanaContainer in…
- Cannot set Elasticsearch URL when using Elasticsearch…
- Service account token cannot be empty
- Service token cannot have leading or trailing whitespace
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/4f2b4df77e76386d.
Report an issue: GitHub.
Appendix: source
Thrown at modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/ElasticsearchContainer.java:339
httpResult =
execInContainer(
"curl",
"-sS",
"--connect-timeout",
"2",
"--max-time",
"4",
"-o",
"/dev/null",
"-w",
"%{http_code}",
"http://localhost:" + ELASTICSEARCH_DEFAULT_PORT + "/"
);
if (httpResult.getExitCode() == 0 && !"000".equals(httpResult.getStdout().trim())) {
return "http";
}
} catch (Exception e) {
throw new RuntimeException("Failed to detect protocol via curl", e);
}
throw new RuntimeException(
String.format(
"Failed to detect protocol via curl. Both HTTPS and HTTP probes failed. " +
"HTTPS probe - exit code: %d, stdout: %s, stderr: %s; " +
"HTTP probe - exit code: %d, stdout: %s, stderr: %s",
httpsResult.getExitCode(),
httpsResult.getStdout(),
httpsResult.getStderr(),
httpResult.getExitCode(),
httpResult.getStdout(),
httpResult.getStderr()
)
);
}
// The TransportClient will be removed in Elasticsearch 8. No need to expose this port anymore in the future.View on GitHub (pinned to 8e549514e3)