skip to content

Explain the configuration precedence hierarchy in Kafka: how is the effective value of a broker/topic config resolved across per-broker, cluster-default, static, and built-in defaults?

level: seniorimportance: should knowfreq 50%

answer

  1. per-broker > cluster-default > static > built-in
  2. topic override > inherited broker log.* default
  3. ConfigSource names tell you the origin
  4. --describe --all shows source
  5. static is below BOTH dynamic sources

basics

~10 s

Kafka resolves the most specific source first: per-broker dynamic, then cluster-wide dynamic default, then the static server.properties value, then the hardcoded default. Topic-level overrides win over the broker default for that topic.

solid answer

~40 s

Effective config is resolved by specificity. For broker configs the order is: (1) per-broker dynamic config (set with --entity-name <id>), (2) cluster-wide dynamic default (--entity-default), (3) the value in that broker's server.properties, (4) Kafka's built-in default. The first source that defines the key wins. For a topic, a per-topic override (DYNAMIC_TOPIC_CONFIG) beats the broker-level default that the topic would otherwise inherit (e.g. topic retention.ms overrides broker log.retention.ms), which itself resolves through the broker hierarchy. kafka-configs --describe --all exposes each value's ConfigSource (DYNAMIC_BROKER_CONFIG, DYNAMIC_DEFAULT_BROKER_CONFIG, STATIC_BROKER_CONFIG, DEFAULT_CONFIG, DYNAMIC_TOPIC_CONFIG) so you can see exactly why a value is what it is. This lets you set a safe cluster-wide default and override it on a single broker without editing files.

go deeper

for a junior

Know that the most specific override wins and topic overrides beat broker defaults.

for a middle

List the broker precedence order and that --describe --all shows the source.

for a senior

Reason about debugging divergent effective values across brokers using ConfigSource.

for a principal

Architect a layered config strategy: cluster defaults + targeted per-broker/per-topic overrides, with auditability via config sources.

## The idea: most specific wins Kafka may have the *same* config key defined in several places. To get a single **effective value** it walks sources from most specific to least specific and takes the **first** one that defines the key. ## Broker config resolution order 1. **Per-broker dynamic config** — set with `kafka-configs --entity-type brokers --entity-name 3 --alter --add-config ...`. Applies to broker 3 only. Source name: `DYNAMIC_BROKER_CONFIG`. 2. **Cluster-wide dynamic default** — set with `--entity-default` (no specific id). Applies to every broker. Source: `DYNAMIC_DEFAULT_BROKER_CONFIG`. 3. **Static** — the value in that broker's `server.properties`. Source: `STATIC_BROKER_CONFIG`. 4. **Built-in default** — Kafka's compiled-in default. Source: `DEFAULT_CONFIG`. So if broker 3 has a per-broker value, it ignores the cluster default, the file, and the built-in. If only a cluster default exists, every broker uses it unless one has a per-broker override. ## Topic config resolution Many topic configs inherit from a broker-level config when not set on the topic: - topic `retention.ms` ⟵ broker `log.retention.ms` - topic `cleanup.policy` ⟵ broker `log.cleanup.policy` - topic `min.insync.replicas` ⟵ broker `min.insync.replicas` Resolution for a topic key: a **per-topic override** (`DYNAMIC_TOPIC_CONFIG`, set via `--entity-type topics`) wins; if absent, the topic inherits the broker-level value, which itself is resolved through the broker hierarchy above. ## Seeing the source ``` kafka-configs.sh --bootstrap-server b:9092 \ --entity-type brokers --entity-name 3 --describe --all ``` `--all` prints every config with its value **and its ConfigSource**, so you can debug "why is retention 7 days here but 1 day there?" — the source tells you whether it came from a per-broker override, the cluster default, the file, or the built-in. ## Why this design is useful - Set one **cluster-wide** safe default once; brokers with special hardware get a **per-broker** override without touching files. - A topic owner sets a per-topic retention without affecting the cluster. - Because dynamic values live in metadata, the hierarchy is consistent across restarts. ## Edge cases / pitfalls - A value in `server.properties` does **not** override a cluster-wide or per-broker dynamic value — static is lower priority than both dynamic sources. - Deleting the per-broker override doesn't reset to the file; it falls to the next source in order (cluster default, then file, then built-in). - Some sensitive configs and some read-only configs aren't dynamically settable, so their effective value comes only from static/default.

  • How can you tell exactly which source a given effective value came from?
    Run kafka-configs --describe --all; each config line includes its ConfigSource (DYNAMIC_BROKER_CONFIG, DYNAMIC_DEFAULT_BROKER_CONFIG, STATIC_BROKER_CONFIG, DEFAULT_CONFIG, or DYNAMIC_TOPIC_CONFIG).
  • If you delete a per-broker dynamic override, does the broker fall back to server.properties?
    It falls to the next source in precedence — the cluster-wide dynamic default if one exists, otherwise server.properties, otherwise the built-in default.

saying these in an interview costs you the question

  • Claiming server.properties overrides a dynamic cluster default — it does not; static sits below both dynamic sources.
  • Saying topic config and broker config are unrelated — many topic keys inherit from broker log.* defaults.
  • Assuming deleting a per-broker override reverts directly to the static file rather than the next precedence source.

context