A KRaft node will not start on an unformatted log directory. kafka-storage.sh format writes meta.properties (cluster, node and random directory IDs) and, on controllers, a bootstrap checkpoint with the feature levels and voters. Since Kafka 3.9 129 quorums can be dynamic (KIP-853): the first controllers are formatted with --initial-controllers (--standalone for one), later ones join with --no-initial-controllers and kafka-metadata-quorum.sh add-controller, and nodes find the quorum through controller.quorum.bootstrap.servers. The static controller.quorum.voters list of the single node cannot change while the cluster runs.
#!/bin/bash
# start.sh: fill in this node's ID, format its log directory once, then start the server.
set -e
sed "s/NODE_ID/$NODE_ID/g" /mnt/quorum/$ROLE.properties > /opt/kafka/config/node.properties
if [ "$ROLE" = controller ]; then
FORMAT_ARGS=(--initial-controllers "${INITIAL_CONTROLLERS// /}") # id@host:port:dir-id
else
FORMAT_ARGS=(--no-initial-controllers) # brokers just join
fi
/opt/kafka/bin/kafka-storage.sh format --cluster-id "$CLUSTER_ID" --ignore-formatted \
--config /opt/kafka/config/node.properties "${FORMAT_ARGS[@]}"
exec /opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/node.propertiesOn l3-c1 the result is cluster.id=Wb96LW2BRGSHe9VjFRvWOA, directory.id=5CUtmwF4QDiCN7NVutEiyQ, node.id=1, and kafka-features.sh reports kraft.version 1, a dynamic quorum (the single node reports 0). A node with another cluster's ID refuses to join. Generate IDs with kafka-storage.sh random-uuid.