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.
Effective differences
Common mistakes
These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
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.
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.
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.