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

  1. Retry the test run; upgrade Testcontainers for more robust wait strategies.
  2. Check container logs and curl the mapped management port endpoint /pools/default/nodeServices to inspect the raw body.
  3. Disable/inspect HTTP proxy environment variables that could intercept the request.
  4. 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

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


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)