testcontainers/testcontainers-java · error · IllegalStateException

Cannot configure Zookeeper when using Kraft mode

Error message

Cannot configure Zookeeper when using Kraft mode

What it means

KafkaContainer supports either Zookeeper-based or KRaft operation, but not both. withEmbeddedZookeeper() configures the embedded Zookeeper mode, and if KRaft was already enabled via withKraft(), enabling Zookeeper would produce a contradictory broker configuration, so the method throws IllegalStateException immediately.

Solutions

  1. Remove the withEmbeddedZookeeper() call when using KRaft mode
  2. Keep only one mode: either withKraft() or (withEmbeddedZookeeper/withExternalZookeeper), never both
  3. If tests need both modes, create separate container instances/builders per mode

Example fix

// before
KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:7.4.0"))
    .withKraft()
    .withEmbeddedZookeeper();

// after
KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:7.4.0"))
    .withKraft();
Defensive patterns

Strategy: validation

Validate before calling

boolean kraft = /* builder flag */;
if (kraft && usesZookeeper) throw new IllegalStateException("Choose either KRaft or Zookeeper, not both");

Try / catch

try {
  kafka = new KafkaContainer(IMAGE).withKraft().withEmbeddedZookeeper();
} catch (IllegalStateException e) {
  if (e.getMessage().contains("Kraft")) { kafka = new KafkaContainer(IMAGE).withKraft(); }
  else throw e;
}

Prevention

When it happens

Trigger: Calling kafkaContainer.withKraft().withEmbeddedZookeeper() — i.e. any withEmbeddedZookeeper() call after kraftEnabled is true.

Common situations: Migrating tests from Zookeeper-based to KRaft mode and keeping old withEmbeddedZookeeper() calls; copy-pasting configuration from different examples; a shared test fixture that sets withKraft() while individual tests also call withEmbeddedZookeeper().

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/3e94eef5cd43cfb7. Report an issue: GitHub.

Appendix: source

Thrown at modules/kafka/src/main/java/org/testcontainers/containers/KafkaContainer.java:92

    public KafkaContainer(final DockerImageName dockerImageName) {
        super(dockerImageName);
        dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
    }

    @Override
    KafkaContainerDef createContainerDef() {
        return new KafkaContainerDef();
    }

    @Override
    KafkaContainerDef getContainerDef() {
        return (KafkaContainerDef) super.getContainerDef();
    }

    public KafkaContainer withEmbeddedZookeeper() {
        if (this.kraftEnabled) {
            throw new IllegalStateException("Cannot configure Zookeeper when using Kraft mode");
        }
        this.externalZookeeperConnect = null;
        return self();
    }

    public KafkaContainer withExternalZookeeper(String connectString) {
        if (this.kraftEnabled) {
            throw new IllegalStateException("Cannot configure Zookeeper when using Kraft mode");
        }
        this.externalZookeeperConnect = connectString;
        return self();
    }

    public KafkaContainer withKraft() {
        if (this.externalZookeeperConnect != null) {
            throw new IllegalStateException("Cannot configure Kraft mode when Zookeeper configured");
        }
        verifyMinKraftVersion();

View on GitHub (pinned to 8e549514e3)