testcontainers/testcontainers-java · error · IllegalStateException
Couchbase /pools/default/nodeServices did not return valid…
Error message
Couchbase /pools/default/nodeServices did not return valid JSON
What it means
initializeHasTlsPorts() GETs /pools/default/nodeServices from the management API to discover which services expose TLS ports (e.g. mgmtSSL under nodesExt[0].services). If the body cannot be parsed as JSON (IOException), the container throws IllegalStateException since TLS port detection is required for further configuration.
Solutions
- Retry the test run; upgrade Testcontainers for more robust wait strategies.
- Check container logs and curl the mapped management port endpoint /pools/default/nodeServices to inspect the raw body.
- Disable/inspect HTTP proxy environment variables that could intercept the request.
- Ensure the image is an official, complete couchbase server image.
Defensive patterns
Strategy: retry
Validate before calling
ContainerExecResult r = container.execInContainer("curl", "-s", "localhost:8091/pools/default/nodeServices");
// body should be valid JSON before the library parses it
if (!r.getStdout().trim().startsWith("{")) throw new IllegalStateException("nodeServices not ready"); Try / catch
try {
container.start();
} catch (IllegalStateException e) {
if (e.getMessage().contains("nodeServices did not return valid JSON")) {
container.stop();
container.start(); // retry once
} else {
throw e;
}
} Prevention
- Unset proxy env vars in the test JVM environment.
- Use official couchbase images and current Testcontainers versions.
- Check container logs / curl the endpoint on failure.
- Ensure the host has enough memory so the server doesn't error mid-startup.
When it happens
Trigger: The management API returned a non-JSON body for /pools/default/nodeServices during container initialization — e.g. an HTML error page, empty body, or proxy-injected content.
Common situations: Startup race where the node isn't ready; proxy/firewall interference with container HTTP traffic; wrong or corrupted image; server erroring under memory pressure.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- Couchbase /pools did not return valid JSON
- message: response, body=body
- The number of replicas must be between 0 and 3 (inclusive)
- Bucket quota cannot be less than 100MB!
- The provided service (service) has no quota to configure
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/9a0d3f302c30ae83.
Report an issue: GitHub.
Appendix: source
Thrown at modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseContainer.java:424
* Community Edition might support TLS one happy day, so use a "supports TLS" flag separate from
* the "enterprise edition" flag.
*/
private void initializeHasTlsPorts() {
@Cleanup
Response response = doHttpRequest(MGMT_PORT, "/pools/default/nodeServices", "GET", null, true);
try {
String clusterTopology = response.body().string();
hasTlsPorts =
!MAPPER
.readTree(clusterTopology)
.path("nodesExt")
.path(0)
.path("services")
.path("mgmtSSL")
.isMissingNode();
} catch (IOException e) {
throw new IllegalStateException("Couchbase /pools/default/nodeServices did not return valid JSON");
}
}
/**
* Rebinds/renames the internal hostname.
* <p>
* To make sure the internal hostname is different from the external (alternate) address and the SDK can pick it
* up automatically, we bind the internal hostname to the internal IP address.
*/
private void renameNode() {
logger().debug("Renaming Couchbase Node from localhost to {}", getHost());
@Cleanup
Response response = doHttpRequest(
MGMT_PORT,
"/node/controller/rename",
"POST",
new FormBody.Builder().add("hostname", getInternalIpAddress()).build(),View on GitHub (pinned to 8e549514e3)