testcontainers/testcontainers-java · error · IllegalStateException

Elasticsearch container is not connected to the expected…

Error message

Elasticsearch container is not connected to the expected network. Ensure both containers use the same Network instance.

What it means

Thrown by resolveExistingEsDnsNameOnNetwork when Docker reports the Elasticsearch container's network endpoints but none matches the expected Network — findNetworkEndpoint returns null. The Elasticsearch container is not attached to the same network Kibana expects, so no DNS name on that network exists.

Solutions

  1. Ensure the exact same Network instance is passed to both elasticsearch.withNetwork() and kibana.withNetwork() before start().
  2. Check docker network inspect <net> to confirm the ES container is attached.
  3. Remove explicit networks so KibanaContainer creates and attaches both containers to one network automatically.

Example fix

// before
elasticsearch.withNetwork(Network.newNetwork());
kibana.withNetwork(sharedNetwork); // ES not on this network
// after
elasticsearch.withNetwork(sharedNetwork);
kibana.withNetwork(sharedNetwork);
Defensive patterns

Strategy: validation

Validate before calling

Network shared = Network.newNetwork();
elasticsearch.withNetwork(shared);
kibana.withNetwork(shared);
assert elasticsearch.getNetwork() == kibana.getNetwork();

Type guard

boolean esOnNetwork(ElasticsearchContainer es, Network n) { return n != null && n == es.getNetwork(); }

Try / catch

try { kibana.start(); } catch (IllegalStateException e) { if (e.getMessage().contains("not connected to the expected network")) throw new ConfigException("Attach ES to the exact same Network instance as Kibana"); throw e; }

Prevention

When it happens

Trigger: Managed mode where the ES container was connected to a different Network instance than Kibana despite earlier checks (e.g. network set after construction, or a Docker network alias/ID mismatch between keying by name vs ID).

Common situations: Attaching networks programmatically after containers started; creating the Network once per test class on one container but a new instance on the other; Docker inspect keyed by network ID vs name edge cases.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/KibanaContainer.java:431

        // We don't need to provide an explicit alias - we'll use the container name for DNS resolution.
        // Equivalent of https://docs.docker.com/reference/cli/docker/network/connect/
        connectRunningContainerToNetwork(esId, createdSharedNetwork);
    }

    private String resolveExistingEsDnsNameOnNetwork(Network network) {
        String esId = requireElasticsearchContainerId();

        InspectContainerResponse info = DockerClientFactory.instance().client().inspectContainerCmd(esId).exec();

        Map<String, ContainerNetwork> networks = info.getNetworkSettings().getNetworks();
        if (networks == null) {
            throw new IllegalStateException("Elasticsearch container has no network configuration");
        }

        // Try to find the network endpoint - Docker may key by network name or ID
        ContainerNetwork endpoint = findNetworkEndpoint(networks, network);
        if (endpoint == null) {
            throw new IllegalStateException(
                "Elasticsearch container is not connected to the expected network. " +
                "Ensure both containers use the same Network instance."
            );
        }

        // Prefer user-defined network aliases (skip Testcontainers auto-generated tc-* aliases)
        if (endpoint.getAliases() != null && !endpoint.getAliases().isEmpty()) {
            for (String alias : endpoint.getAliases()) {
                if (StringUtils.isNotBlank(alias)) {
                    String cleaned = alias.trim();
                    // Skip Testcontainers auto-generated aliases (tc-*), prefer user-defined ones
                    if (!cleaned.startsWith("tc-")) {
                        log.info("Using Elasticsearch network alias: {}", cleaned);
                        return cleaned;
                    }
                }
            }
        }

View on GitHub (pinned to 8e549514e3)