{"record":{"id":"9b1bd8598c8463ed","repo":"testcontainers/testcontainers-java","slug":"cannot-configure-kraft-mode-when-zookeeper-configured","errorCode":null,"errorMessage":"Cannot configure Kraft mode when Zookeeper configured","messagePattern":"Cannot configure Kraft mode when Zookeeper configured","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/kafka/src/main/java/org/testcontainers/containers/KafkaContainer.java","lineNumber":108,"sourceCode":"    public KafkaContainer withEmbeddedZookeeper() {\n        if (this.kraftEnabled) {\n            throw new IllegalStateException(\"Cannot configure Zookeeper when using Kraft mode\");\n        }\n        this.externalZookeeperConnect = null;\n        return self();\n    }\n\n    public KafkaContainer withExternalZookeeper(String connectString) {\n        if (this.kraftEnabled) {\n            throw new IllegalStateException(\"Cannot configure Zookeeper when using Kraft mode\");\n        }\n        this.externalZookeeperConnect = connectString;\n        return self();\n    }\n\n    public KafkaContainer withKraft() {\n        if (this.externalZookeeperConnect != null) {\n            throw new IllegalStateException(\"Cannot configure Kraft mode when Zookeeper configured\");\n        }\n        verifyMinKraftVersion();\n        this.kraftEnabled = true;\n        return self();\n    }\n\n    private void verifyMinKraftVersion() {\n        String actualVersion = DockerImageName.parse(getDockerImageName()).getVersionPart();\n        if (new ComparableVersion(actualVersion).isLessThan(MIN_KRAFT_TAG)) {\n            throw new IllegalArgumentException(\n                String.format(\n                    \"Provided Confluent Platform's version %s is not supported in Kraft mode (must be %s or above)\",\n                    actualVersion,\n                    MIN_KRAFT_TAG\n                )\n            );\n        }\n    }","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/testcontainers/testcontainers-java/blob/8e549514e3f01c57d70546fbb8599d138f3903e5/modules/kafka/src/main/java/org/testcontainers/containers/KafkaContainer.java#L90-L126","documentation":"withKraft() enables KRaft (Zookeeper-less) mode, but if a Zookeeper configuration was already applied via withEmbeddedZookeeper() or withExternalZookeeper(), the settings are mutually exclusive. The method throws IllegalStateException to prevent building a broker config that mixes KRaft with Zookeeper.","triggerScenarios":"Calling kafkaContainer.withEmbeddedZookeeper().withKraft() or kafkaContainer.withExternalZookeeper(\"zk:2181\").withKraft() — any withKraft() call after externalZookeeperConnect/embedded zookeeper was set.","commonSituations":"Adding withKraft() to an existing Zookeeper-based test setup to 'modernize' it without removing old calls; base test classes that configure Zookeeper while subclasses enable KRaft; copy-pasted fluent chains combining examples.","solutions":["Remove the preceding withEmbeddedZookeeper()/withExternalZookeeper() calls and keep only withKraft()","Guard the chain with an if/else so only one mode is configured","Start from a clean KafkaContainer instance when switching modes"],"exampleFix":"// before\nKafkaContainer kafka = new KafkaContainer(DOCKER_IMAGE)\n    .withEmbeddedZookeeper()\n    .withKraft();\n\n// after\nKafkaContainer kafka = new KafkaContainer(DOCKER_IMAGE)\n    .withKraft();","handlingStrategy":"validation","validationCode":"if (zookeeperConfigured) throw new IllegalStateException(\"Remove withEmbeddedZookeeper/withExternalZookeeper before calling withKraft()\");","typeGuard":null,"tryCatchPattern":"try {\n  kafka = new KafkaContainer(IMAGE).withEmbeddedZookeeper().withKraft();\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"Zookeeper configured\")) { kafka = new KafkaContainer(IMAGE).withKraft(); }\n  else throw e;\n}","preventionTips":["Call withKraft() first and never mix in zookeeper setters","Wrap Kafka container creation in a single utility that enforces one mode","When converting old tests, remove Zookeeper calls instead of appending withKraft","Add a unit test asserting the fluent chain throws on mixed config"],"tags":["kafka","kraft","zookeeper","configuration-conflict"],"backgroundTag":"conflicting-config-options","analyzedSha":"8e549514e3f01c57d70546fbb8599d138f3903e5","analyzedAt":"2026-09-12T14:56:41.227Z","contentChangedAt":"2026-09-12T14:56:41.227Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}