Kafka ZooKeeper to KRaft Config Converter

Turn a ZooKeeper-mode server.properties into a KRaft one. Every setting is sorted into carries across, renamed, or no equivalent at all, and nothing is dropped silently: the ones with no counterpart are commented with the reason.

Three controllers tolerate one failure; an even number tolerates the same as the odd number below it. Combined mode is for development, where it saves running separate processes.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Convert. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

A ZooKeeper broker config

What converts, what has no KRaft equivalent, and why this is a migration not a conversion

zookeeper.connect=zk:2181
broker.id=1
log.dirs=/var/lib/kafka

Controller quorum

The settings a KRaft cluster needs that a ZooKeeper one never had

broker.id=1
log.dirs=/var/lib/kafka
num.partitions=6

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Treating the config conversion as the migration

    Converting settings is the easy part. The metadata itself has to move, which is a documented multi-step procedure with a dual-write phase.

    Instead:Follow the migration procedure. This page only shows the config side.

  2. Forgetting to format the storage directory

    KRaft needs kafka-storage.sh format with a cluster id before the first start, which ZooKeeper never required.

    Instead:Format before starting, and keep the cluster id.

  3. Assuming every setting has an equivalent

    Several ZooKeeper-era settings have no KRaft counterpart and are simply gone.

    Instead:Read the ones flagged as having no equivalent rather than translating them.

Converting the config is the easy half

Most settings carry across untouched. The ones that do not divide into renames, which are harmless, and settings with no KRaft equivalent at all, which is where a migration goes wrong.

The authorizer class changes, and nothing about its name says so

AclAuthorizer stores and reads ACLs in ZooKeeper, so it cannot work in KRaft; StandardAuthorizer keeps them in the metadata log. A KRaft broker configured with the ZooKeeper authorizer fails to start. Worse, converting the config without running the actual metadata migration leaves you with an authorizing cluster whose ACLs are still in ZooKeeper, which denies everything. This is the single most commonly missed step.

# ZooKeeper mode
authorizer.class.name=kafka.security.authorizer.AclAuthorizer

# KRaft
authorizer.class.name=org.apache.kafka.metadata.\
  authorizer.StandardAuthorizer

inter.broker.protocol.version stops doing anything

In KRaft the cluster-wide protocol level is a feature called metadata.version, raised with kafka-features rather than by editing every broker's config. Left in a KRaft server.properties it is simply ignored. That matters because pinning it is what gives a rolling upgrade its rollback window: a config carried across looks pinned and is not.

Log directories have to be formatted before first start

KRaft keeps cluster metadata in the log directory, so kafka-storage format runs once per node with the same cluster id across the whole cluster. A node started against an unformatted directory refuses to start; one formatted with a different cluster id refuses to join. Generate the id once and reuse it everywhere.

KAFKA_CLUSTER_ID=$(bin/kafka-storage.sh random-uuid)

# on every node, with the SAME id
bin/kafka-storage.sh format \
  --cluster-id $KAFKA_CLUSTER_ID \
  --config config/server.properties

An even number of controllers buys nothing

The controller quorum needs a majority, so tolerance is (n-1)/2 rounded down: one controller tolerates no failures, three tolerate one, five tolerate two. Two controllers tolerate no failures and cost twice as much as one, because losing either loses the majority. Three is the answer for almost every cluster.

Combined mode is for laptops

process.roles=broker,controller puts the quorum on the same JVMs serving client traffic, so a broker under load is a controller under load and losing a node loses both roles. It is genuinely fine for development and Kafka's own documentation recommends dedicated controllers for production.

This is not a migration tool

It produces the config a KRaft node needs, which is what you want for a new cluster or as the target state for a real migration. Moving an existing cluster's topics, ACLs and consumer offsets out of ZooKeeper is a separate operation that runs on a 3.x release and must complete before the 4.0 upgrade, because 4.0 has no ZooKeeper support left to migrate from. The version compatibility reference on this site has the ordering.