Kafka Config Diff

Compare two Kafka configs by what they mean rather than by their text. Key order, comments and duplicate keys are resolved the way a client resolves them, the values that are spelled differently and mean the same thing are named as such, and a deleted line is reported as the fallback to a default that it actually is.

Nothing is uploaded: the comparison runs in this tab.

Common mistakes

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

  1. Diffing a config file against a running broker

    Command line overrides and dynamic config beat the file, so a file diff can show a difference that does not exist and miss one that does.

    Instead:Compare against kafka-configs --describe output for the truth.

  2. Treating an added default as a change

    A key absent from one side is not necessarily different: it may be at the same value by default. A textual diff cannot tell.

    Instead:Compare resolved values, which is what this page does.

  3. Applying a diff without checking which settings need a restart

    Some settings are dynamic and some are not. Applying them all with kafka-configs silently skips the static ones.

    Instead:Split the change into dynamic and restart-required.

What it refuses to call a difference

Most of the value of a semantic diff is in what it declines to tell you, and the rest is in the one thing a text diff cannot see at all.

acks=-1 and acks=all are the same setting

Kafka accepts both spellings and treats them identically, so a text diff reporting a change there sends you looking for one that does not exist. The same goes for a boolean written TRUE on one side and true on the other, because Kafka reads booleans case-insensitively. Both are reported here as written differently and meaning the same thing, which is a different statement from no difference at all.

A deleted line is not a no-op

Removing acks=all does not leave the value where it was. It leaves it at the client's default, and that default changed in Kafka 3.0 from 1 to all, along with enable.idempotence. So the same deletion means a replicated write on a 3.0 client and a silently lossy one on an older client. Nothing in a text diff can tell you that, and the removal reads as tidying up.

Guarantee changes are separated from tuning

acks, min.insync.replicas, unclean.leader.election.enable, isolation.level and enable.auto.commit change what Kafka promises about your data. linger.ms and batch.size change how fast it goes. A forty-row diff buries the three rows of the first kind among the thirty-seven of the second, so they are ranked and counted separately.

A duplicate key is resolved, and reported

Java's Properties.load takes the last occurrence of a key and says nothing about the earlier ones. A file with two acks lines therefore does not do what a reader scanning it top to bottom expects. Both sides are resolved the way a client would resolve them, so a duplicate never shows up as a false difference, and the duplicate itself is reported as its own finding.

Why diffing two Kafka configs as text mostly wastes your time

A Kafka config is a Java .properties file, and comparing two of them looks like a job for diff. In practice a line-by-line comparison reports differences that are not differences, misses the one change that alters your durability guarantee, and cannot see the change that consists of a line no longer being there.

The format is not key=value

Java .properties allows =, : or bare whitespace as the separator, treats # and ! as comments, resolves \t and \uXXXX escapes, and continues a line that ends in an odd number of backslashes. That last rule is the one that matters in Kafka, because sasl.jaas.config is routinely written across several lines. A comparison that splits on = reads the first line of that property and drops the half containing the credential.

one property, spanning two lines

sasl.jaas.config=org.apache.kafka...PlainLoginModule required \
  username="alice" password="s3cret";

split on "=" and you get:
  key   sasl.jaas.config
  value org.apache.kafka...PlainLoginModule required
        (the credential is gone)

Values that differ as text and not as configuration

acks takes 0, 1, all or -1, and -1 is a synonym for all rather than a different setting. Booleans are read case-insensitively, so TRUE and true are one value. Key order carries no meaning, blank lines and comments carry none, and a duplicated key resolves to whichever occurrence came last. Every one of those is a difference to diff and none of them is a difference to Kafka.

these two configs are identical to Kafka

acks=-1                     acks=all
enable.idempotence=TRUE     enable.idempotence=true
linger.ms=5                 # tuned 2026-01
                            linger.ms=5

diff: 4 changed lines. Kafka: no change.

The change that is an absence

This is the one worth the page. When a setting is deleted, the value does not stay where it was: it falls back to the default for the client or broker version in use. Kafka 3.0 turned enable.idempotence on by default, which in turn forces acks=all, and 2.1 changed retries from 0 to effectively unbounded. So deleting acks=all from a producer config is harmless on a 3.0 client and turns a replicated write into a leader-only one on a 2.8 client. The line is gone either way, and only the version tells you which happened.

- acks=all

on a 3.0+ client   default is all   no change
on a 2.8 client    default is 1     leader-only writes,
                                    lost if it fails
                                    before replicating

Guarantees and tuning are not the same kind of change

Some settings decide whether an acknowledged write can be lost, whether a consumer can skip records, and whether aborted transactional messages are visible. Others decide throughput and latency. Both appear in the same file and look alike, so a diff sorted by key name interleaves them. Here the first kind is ranked above the second and counted in the verdict, and the verdict fails only when one of them changed.

changes that alter a promise

acks                    min.insync.replicas
enable.idempotence      unclean.leader.election.enable
enable.auto.commit      isolation.level
auto.offset.reset       retention.ms

changes that alter speed

linger.ms  batch.size  compression.type  buffer.memory

Credentials are compared and never printed

A config diff is an unusually convenient way to leak two passwords at once, because the natural output shows the old value and the new one side by side. Any key that looks like a password, a keystore secret, a token or a jaas config is compared normally, so a change is reported, and neither side is rendered. The comparison runs in this browser tab and nothing is uploaded, which is why pasting a real config here is safe in a way that pasting it into a server-side diff tool is not.

What this does not know

It reads two files. It does not know your Kafka version, so where a default moved it names both values rather than picking one. It does not know your broker's own limits, so a session timeout outside group.min.session.timeout.ms is invisible here. And it does not validate values: acks=2 is reported as a change from acks=1 rather than as the invalid setting it is. The producer and consumer config linters on this site do that part, and the replication safety checker reads acks, min.insync.replicas and replication.factor together, which is the only way any of the three means anything.

More kafka tools

Kafka Confluent Wire Format Decoder The five junk bytes in front of your payload Kafka Key to Partition Mapper Which partition does this key land on? Kafka Topic Name Validator Legal, risky, or 249 characters too long? Kafka Replication Safety Checker How many brokers can you lose Kafka Producer Config Linter Will it start, and will it lose a record? Kafka Message Payload Decoder The first five bytes are usually not data Kafka Connect Source Connector Generator tasks.max is a ceiling, not a count Kafka Connect Sink Connector Generator A dead letter queue with no context headers is a pile of records Kafka Connect SMT Chain Builder The order is the transforms list Kafka MirrorMaker 2 Config Generator It renames every topic by default Kafka Partition Reassignment Generator The throttle is not optional Strimzi Kafka Resource Generator Without the cluster label, nothing happens Kafka mTLS Config Generator The certificate is the identity Kafka Schema Registry Config Generator The compatibility direction is your deployment order Kafka Exactly-Once Config Generator Half of it is worse than none Kafka Broker and KRaft Config Generator The internal topics that break a one-broker cluster Kafka Quota Generator Byte rates are per broker, not per cluster Kafka Streams Config Generator application.id is four things at once Kafka Connect Worker Config Generator Security three times, or the tasks fail Kafka Retention and Unit Converter log.retention.hours does not take milliseconds Kafka Timestamp Converter Two sentinels and two meanings Kafka .properties to YAML Converter Dotted keys stay flat Kafka Streams Internal Topic Predictor Create them before Streams does Kafka ACL Generator The grant you forgot is on another resource type Kafka Topic Config Generator min.insync.replicas is the one that matters Kafka client.properties Generator The file every CLI tool asks for Kafka Producer Config Generator No password field, on purpose Kafka Consumer Config Generator The commit mode decides the semantics Kafka Disk and Retention Calculator retention.bytes is per partition Kafka Partition Count Calculator The number you can never reduce Kafka Cluster Sizing Calculator The traffic no client metric shows Kafka Consumer Lag Catch-Up Calculator Whether it ever clears, not just when Kafka Producer Batching Calculator linger.ms=0 still batches Kafka Segment and Index Sizing Why retention.ms is a lower bound Kafka Rebalance Duration Estimator What a rolling restart really costs Kafka Cost Estimator Your rates, so nothing goes stale Kafka Config Explorer by Version The answer depends on the release Kafka Default Config Reference What moved under a config you never edited Kafka OAuth Bearer Token Decoder Will Kafka accept it, and can it refresh Kafka Record Header Viewer Headers are a list, not a map Kafka Topic Regex Subscription Tester Kafka matches the whole name Kafka ACL Permission Matrix Viewer DENY beats every ALLOW Kafka Connect Config Validator The mistakes that raise no error Kafka Consumer Group Id Validator Which broker coordinates the group Kafka Partition Assignment Visualizer Leadership is the load, not replicas Kafka Consumer Assignment Visualizer The three assignors disagree Kafka ZooKeeper to KRaft Config Converter The authorizer class nobody changes Kafka Config to Strimzi Half of it belongs elsewhere Kafka Docker Compose Generator (KRaft) Reachable from inside and outside Kafka JAAS Config Decoder The line that stops SASL working Kafka CRC32C Calculator Which CRC, over which bytes Kafka Config Upgrade Checker What breaks when you upgrade Kafka Kafka Consumer Config Linter Why the group rebalances, and where the records went Kafka Avro Schema Validator The defaults Avro accepts and rejects Kafka Schema Compatibility Checker What the registry will say, before you ask it Kafka Avro Schema Diff Which direction each change breaks Kafka Compression Comparison Measured on your bytes Kafka Delivery Semantics Exactly-once has a consumer half Kafka ksqlDB Query Builder It looks like SQL and the rules are not Kafka Connect SMT Predicate Tester negate reads backwards Kafka Streams Topology Viewer Count the repartitions Kafka Connect Pipeline Visualizer The order things really run in Kafka Protobuf Binary Decoder Works without the .proto Kafka Protobuf JSON Converter Why your JSON does not round-trip Kafka Protobuf to Avro Schema What does not survive the conversion Kafka Avro Binary Decoder Wrong schema, no error Kafka Avro JSON Converter Why the console producer rejects your line Kafka Avro Sample Data Generator Records that actually serialize Kafka JSON to Avro Schema What JSON cannot tell you Kafka JSON Schema to Avro What does not survive the conversion Kafka SASL JAAS Generator One login module, four syntaxes Kafka CLI Command Builder kcat is librdkafka, not Kafka

Elsewhere on the site