{"record":{"id":"9b322d2597ce30a7","repo":"testcontainers/testcontainers-java","slug":"elasticsearch-must-be-configured-either-via-constructor","errorCode":null,"errorMessage":"Elasticsearch must be configured either via constructor KibanaContainer(elasticsearch) or via .withElasticsearchUrl() for external Elasticsearch","messagePattern":"Elasticsearch must be configured either via constructor KibanaContainer\\(elasticsearch\\) or via \\.withElasticsearchUrl\\(\\) for external Elasticsearch","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/KibanaContainer.java","lineNumber":277,"sourceCode":"    }\n\n    @Override\n    protected void configure() {\n        super.configure();\n\n        addEnv(\"XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY\", encryptionKey);\n        addEnv(\"SERVER_NAME\", \"kibana\");\n\n        if (elasticsearchCaCertificate != null) {\n            withCopyToContainer(Transferable.of(elasticsearchCaCertificate), ES_CA_CERT_PATH);\n            addEnv(\"ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES\", ES_CA_CERT_PATH);\n        }\n        if (elasticsearch != null) {\n            configureManagedElasticsearch();\n        } else if (elasticsearchUrl != null) {\n            configureExternalElasticsearch();\n        } else {\n            throw new IllegalStateException(\n                \"Elasticsearch must be configured either via constructor KibanaContainer(elasticsearch) \" +\n                \"or via .withElasticsearchUrl() for external Elasticsearch\"\n            );\n        }\n        //wait strategy is set in configure, because we don't know the security configuration before\n        configureWaitStrategy();\n    }\n\n    @Override\n    protected void containerIsStarted(InspectContainerResponse containerInfo) {\n        super.containerIsStarted(containerInfo);\n        log.info(\"Kibana is now ready, it can be accessed at http://{}\", getHttpHostAddress());\n    }\n\n    @Override\n    public void stop() {\n        super.stop();\n        if (createdSharedNetwork != null) {","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/testcontainers/testcontainers-java/blob/8e549514e3f01c57d70546fbb8599d138f3903e5/modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/KibanaContainer.java#L259-L295","documentation":"Thrown during KibanaContainer.configure() when neither a managed ElasticsearchContainer was supplied via the constructor nor an external Elasticsearch URL was set via withElasticsearchUrl(). Kibana needs a target Elasticsearch cluster, so the container cannot be started without one of the two configuration paths.","triggerScenarios":"Instantiating new KibanaContainer() with the no-arg constructor and starting it without calling withElasticsearchUrl(); or clearing/never setting both elasticsearch and elasticsearchUrl before start().","commonSituations":"Refactoring code that previously used the KibanaContainer(elasticsearch) constructor to the no-arg constructor and forgetting to add withElasticsearchUrl; building the container generically from config where both branches were skipped.","solutions":["Construct with a managed container: new KibanaContainer(new ElasticsearchContainer(...)) or elasticsearch container instance.","For an external cluster, call kibana.withElasticsearchUrl(\"https://es.example.com:9200\") before start().","Verify your config-loading code actually sets one of the two options."],"exampleFix":"// before\nKibanaContainer kibana = new KibanaContainer();\nkibana.start();\n// after\nKibanaContainer kibana = new KibanaContainer(elasticsearchContainer);\n// or, for external ES:\nKibanaContainer kibana = new KibanaContainer().withElasticsearchUrl(\"http://es:9200\");\nkibana.start();","handlingStrategy":"validation","validationCode":"KibanaContainer kb = elasticsearch != null ? new KibanaContainer(elasticsearch)\n    : esUrl != null ? new KibanaContainer().withElasticsearchUrl(esUrl)\n    : throw new IllegalArgumentException(\"Provide an ElasticsearchContainer or an Elasticsearch URL\");","typeGuard":"boolean isConfigured(KibanaContainer kb) { return kb != null && (managedEs != null || esUrl != null); }","tryCatchPattern":"try { kibana.start(); } catch (IllegalStateException e) { if (e.getMessage().contains(\"must be configured\")) throw new ConfigException(\"Set KibanaContainer(elasticsearch) or withElasticsearchUrl()\"); throw e; }","preventionTips":["Always construct KibanaContainer with an ElasticsearchContainer or immediately call withElasticsearchUrl","Centralize Kibana test-container creation in one factory method","Add an assertion in test setup that one of the two config paths was taken"],"tags":["configuration","elasticsearch","testcontainers","missing-config"],"backgroundTag":"missing-required-config","analyzedSha":"8e549514e3f01c57d70546fbb8599d138f3903e5","analyzedAt":"2026-09-12T14:56:41.227Z","contentChangedAt":"2026-09-12T14:56:41.227Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}