testcontainers/testcontainers-java · error · IllegalStateException
Elasticsearch must be configured either via constructor…
Error message
Elasticsearch must be configured either via constructor KibanaContainer(elasticsearch) or via .withElasticsearchUrl() for external Elasticsearch
What it means
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.
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.
Example fix
// before
KibanaContainer kibana = new KibanaContainer();
kibana.start();
// after
KibanaContainer kibana = new KibanaContainer(elasticsearchContainer);
// or, for external ES:
KibanaContainer kibana = new KibanaContainer().withElasticsearchUrl("http://es:9200");
kibana.start(); Defensive patterns
Strategy: validation
Validate before calling
KibanaContainer kb = elasticsearch != null ? new KibanaContainer(elasticsearch)
: esUrl != null ? new KibanaContainer().withElasticsearchUrl(esUrl)
: throw new IllegalArgumentException("Provide an ElasticsearchContainer or an Elasticsearch URL"); Type guard
boolean isConfigured(KibanaContainer kb) { return kb != null && (managedEs != null || esUrl != null); } Try / catch
try { kibana.start(); } catch (IllegalStateException e) { if (e.getMessage().contains("must be configured")) throw new ConfigException("Set KibanaContainer(elasticsearch) or withElasticsearchUrl()"); throw e; } Prevention
- 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
When it happens
Trigger: Instantiating new KibanaContainer() with the no-arg constructor and starting it without calling withElasticsearchUrl(); or clearing/never setting both elasticsearch and elasticsearchUrl before start().
Common situations: 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.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- Managed mode requires either both containers share the same…
- Elasticsearch and Kibana have different networks…
- Changing startup timeout is not supported with mode
- Unexpected scheme
- Setting a in not supported in the versions below 22.1.0
AI-assisted analysis of testcontainers/testcontainers-java@8e549514e3 (2026-09-12).
Data as JSON: /api/errors/9b322d2597ce30a7.
Report an issue: GitHub.
Appendix: source
Thrown at modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/KibanaContainer.java:277
}
@Override
protected void configure() {
super.configure();
addEnv("XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY", encryptionKey);
addEnv("SERVER_NAME", "kibana");
if (elasticsearchCaCertificate != null) {
withCopyToContainer(Transferable.of(elasticsearchCaCertificate), ES_CA_CERT_PATH);
addEnv("ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES", ES_CA_CERT_PATH);
}
if (elasticsearch != null) {
configureManagedElasticsearch();
} else if (elasticsearchUrl != null) {
configureExternalElasticsearch();
} else {
throw new IllegalStateException(
"Elasticsearch must be configured either via constructor KibanaContainer(elasticsearch) " +
"or via .withElasticsearchUrl() for external Elasticsearch"
);
}
//wait strategy is set in configure, because we don't know the security configuration before
configureWaitStrategy();
}
@Override
protected void containerIsStarted(InspectContainerResponse containerInfo) {
super.containerIsStarted(containerInfo);
log.info("Kibana is now ready, it can be accessed at http://{}", getHttpHostAddress());
}
@Override
public void stop() {
super.stop();
if (createdSharedNetwork != null) {View on GitHub (pinned to 8e549514e3)