Strimzi KRaft migration: one annotation drives the whole flow
Strimzi turns the KIP-866 migration into a single annotation and a state machine you can watch. The operator handles the rolls — your job is the timing, the version window, and the backup you take before touching cluster metadata.
How the Strimzi KRaft migration works
A Strimzi KRaft migration is the standard Kafka dual-write procedure, driven
by the operator instead of by hand. You annotate the Kafka resource, and
Strimzi deploys KRaft controllers in migration mode, rolls the brokers, and
reports every phase through status.kafkaMetadataState.
Three prerequisites gate the start: Strimzi 0.40 or newer running Kafka 3.7
or newer, node pools enabled on the Kafka resource
(strimzi.io/node-pools: enabled), and the Unidirectional Topic Operator.
There is also a version cliff. Strimzi 0.45.x is the last release line that runs ZooKeeper-based clusters at all — 0.46.0 removed both ZooKeeper support and the migration itself. If your operator is older, plan the upgrade path to 0.45.x first, migrate there, then move past it.
kafkaMetadataState | What the operator is doing | Your move |
|---|---|---|
KRaftMigration | KRaft controllers deployed with the migration flag; metadata copying | Watch and wait |
KRaftDualWriting | Metadata written to both ZooKeeper and the KRaft quorum | Validate the cluster under real traffic |
KRaftPostMigration | Brokers running against KRaft; ZooKeeper still consistent | Decide: finalize with enabled, or roll back |
KRaft | Migration finalized | None — there is no way back from here |
The full sequence, including the self-managed and Confluent paths, is in the complete ZooKeeper to KRaft migration guide. If you are still choosing between platforms or timing, start from the migration path router.
Take the backup before you annotate
The migration rewrites the cluster's metadata layer while workloads keep
running. Strimzi protects the metadata handover; it does nothing for the data
in your topics if a roll goes wrong mid-flight. Because the cluster is
Strimzi-managed, the backup is Strimzi-native too: the
Strimzi Backup Operator resolves bootstrap servers,
cluster CA certificates, and KafkaUser credentials directly from your
custom resources.
- KafkaBackup CR
- Run the migration
apiVersion: kafkabackup.com/v1alpha1
kind: KafkaBackup
metadata:
name: pre-kraft-migration
namespace: kafka
spec:
strimziClusterRef:
name: my-cluster # your Strimzi Kafka CR
storage:
type: s3
s3:
bucket: my-kafka-backups
region: eu-west-1
accessKeySecret:
name: aws-credentials
key: access-key-id
secretKeySecret:
name: aws-credentials
key: secret-access-key
backup:
stopAtCurrentOffsets: true
# Verify the backup Job completed before this point
kubectl get kafkabackups,jobs -n kafka
# Start the migration
kubectl annotate kafka my-cluster strimzi.io/kraft="migration" --overwrite
# Watch kafkaMetadataState progress
kubectl get kafka my-cluster -w
# Finalize — only after validating at KRaftPostMigration
kubectl annotate kafka my-cluster strimzi.io/kraft="enabled" --overwrite
stopAtCurrentOffsets: true gives the backup a clean upper bound: it captures
everything up to the offsets at backup start, then the Job completes and shows
up in kubectl get jobs like any other workload. The
Strimzi backup walkthrough covers scheduling,
restores, and credentials in depth.
Rollback closes at finalization
Until you annotate enabled, there is a way back. From KRaftPostMigration,
annotate strimzi.io/kraft="rollback" (the cluster returns to
KRaftDualWriting), delete the controller KafkaNodePool, then annotate
disabled to return fully to ZooKeeper. Before any retry, delete the
/migration znode in ZooKeeper — the Strimzi docs warn that skipping this
cleanup can cause metadata loss on the next attempt.
Once the state reaches KRaft, the door is closed by Kafka itself, not
Strimzi. That is the moment your pre-migration backup becomes the only copy
of the cluster's pre-KRaft state — hold it until your retention policy clears
it. A backup taken in ZooKeeper mode restores to a KRaft cluster unchanged,
because the storage format depends on the Kafka protocol, not the metadata
layer.
Frequently asked questions
How do I migrate Strimzi from ZooKeeper to KRaft?
Annotate the Kafka resource with strimzi.io/kraft="migration". The operator runs the KIP-866 dual-write flow: it deploys KRaft controllers, rolls brokers into migration mode, and reports progress in status.kafkaMetadataState. At KRaftPostMigration you finalize with strimzi.io/kraft="enabled". Prerequisites: Strimzi 0.40+, Kafka 3.7+, node pools, and the Unidirectional Topic Operator.
Which Strimzi version supports the KRaft migration?
Strimzi 0.40 or newer, running Kafka 3.7 or newer. The window closes at 0.45.x — Strimzi 0.46.0 removed support for ZooKeeper-based clusters and for the migration itself, so ZooKeeper-mode clusters must migrate before upgrading the operator past 0.45.x.
Can I roll back a Strimzi KRaft migration?
Yes, until you finalize. From KRaftPostMigration, annotate strimzi.io/kraft="rollback", delete the controller KafkaNodePool, then annotate "disabled" to return to ZooKeeper. Delete the /migration znode before retrying. Once kafkaMetadataState reaches KRaft, rollback is no longer possible on any platform.
How do I back up a Strimzi cluster before the KRaft migration?
Apply a KafkaBackup custom resource from the Strimzi Backup Operator. It resolves connection details, cluster CA certificates, and KafkaUser credentials from your Strimzi resources and runs the backup as a Kubernetes Job writing to S3, Azure Blob, GCS, or filesystem storage.
Does a backup taken in ZooKeeper mode restore to a KRaft cluster?
Yes. Backups depend on the Kafka protocol, not the metadata layer, so a backup from a ZooKeeper-mode Strimzi cluster restores unchanged to a KRaft-mode cluster — including after the migration finalizes, when no other route back to the old state exists.
Ready to protect your Kafka data?
Take your first backup in minutes with the open source CLI, or talk to us about Enterprise features like encryption, RBAC, and audit logging.