testcontainers/testcontainers-java · error · IllegalStateException

Elasticsearch and Kibana have different networks…

Error message

Elasticsearch and Kibana have different networks configured. In managed mode both containers must share the same explicit network instance, or neither must define a network.

What it means

Thrown by ensureCorrectNetworkSetupForManagedMode when both containers have explicit networks but they are different Network instances (esNetwork != kbNetwork, compared by identity). Kibana could not reach Elasticsearch across unrelated Docker networks in managed mode.

Solutions

  1. Share one Network instance: pass the identical Network object to both elasticsearch.withNetwork() and kibana.withNetwork().
  2. Or drop explicit networks from both containers so KibanaContainer creates and joins them to a single network.
  3. Extract the Network creation into one place shared by both container setups.

Example fix

// before
elasticsearch.withNetwork(Network.newNetwork());
kibana.withNetwork(Network.newNetwork()); // different instance
// after
Network shared = Network.newNetwork();
elasticsearch.withNetwork(shared);
kibana.withNetwork(shared);
Defensive patterns

Strategy: validation

Validate before calling

Network shared = Network.newNetwork();
assert elasticsearch.getNetwork() == kibana.getNetwork() : "ES and Kibana must share the same Network instance";

Type guard

boolean sameNetwork(GenericContainer<?> es, GenericContainer<?> kb) { return es.getNetwork() != null && es.getNetwork() == kb.getNetwork(); }

Try / catch

try { kibana.start(); } catch (IllegalStateException e) { if (e.getMessage().contains("different networks configured")) throw new ConfigException("Reuse one Network instance for both containers"); throw e; }

Prevention

When it happens

Trigger: Creating two separate Network.newNetwork() objects and assigning one to the ElasticsearchContainer and the other to KibanaContainer; or reusing the network name string but different Network instances.

Common situations: Two test setup helpers each creating their own network; constructing networks in different scopes/fixtures so the instances differ even if names collide.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

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

                e
            );
        }
    }

    private void ensureCorrectNetworkSetupForManagedMode() {
        Network esNetwork = elasticsearch.getNetwork();
        Network kbNetwork = this.getNetwork();

        if ((esNetwork == null) != (kbNetwork == null)) {
            throw new IllegalStateException(
                "Managed mode requires either both containers share the same explicit network, " +
                "or neither specifies a network (KibanaContainer will create one). "
            );
        }

        // Both explicit: must be same
        if (esNetwork != kbNetwork) {
            throw new IllegalStateException(
                "Elasticsearch and Kibana have different networks configured. " +
                "In managed mode both containers must share the same explicit network instance, " +
                "or neither must define a network."
            );
        }
    }

    private void createAdHocNetwork() {
        // Fully managed: create ad-hoc network and own it.
        createdSharedNetwork = Network.newNetwork();
        withNetwork(createdSharedNetwork);

        // Managed-mode safety rule: by the time Kibana is configuring itself, Elasticsearch must already be
        // started (via dependsOn)
        String esId = requireElasticsearchContainerId();

        // Elasticsearch is already created/started. Attach it to the ad-hoc network.
        // We don't need to provide an explicit alias - we'll use the container name for DNS resolution.

View on GitHub (pinned to 8e549514e3)