August 18, 2025·4 min read·engineeringkafkaclientsdiagnostics

librdkafka stops treating planned disconnects as a broker outage

Version 2.11.1 corrects all-brokers-down reporting by excluding planned disconnects and invalidating stale failure state after a successful connection.

A closed connection is not necessarily evidence that a broker failed. A client can close an idle connection deliberately or replace one after a hostname change. librdkafka 2.11.1 stops those planned transitions from contributing to an all-brokers-down conclusion.

The August 18 release also corrects the use of cached broker failure states. After a successful connection, the client must try other brokers again before treating their older failures as current evidence. Together, the changes make a broad availability error depend on a more coherent set of observations.

I value Kafka's retained log, but a consumer's error messages describe the client's view of the system. They are not automatically a complete account of the brokers. This patch matters because applications and operators can act on a broad outage signal even when its underlying evidence is stale or intentional.

Planned closure is a state transition

The connection-state patch distinguishes planned disconnections from failures that should contribute to the down count. The release names idle disconnections and broker host changes as examples. Both can leave a connection closed while the service remains available.

An idle timeout is a local lifecycle decision. The client has decided that it does not currently need to retain that connection. Counting the closure as a broker failure changes the meaning of an ordinary resource-management action.

A hostname change has a similar distinction. Replacing an existing connection can be necessary to use an updated address. The old connection's termination does not establish that the newly advertised destination is unavailable.

The fix changes how those transitions enter the client's availability accounting. It does not require keeping every connection open indefinitely. Resource management can continue while its deliberate closures stop being mistaken for evidence of a cluster-wide failure.

That difference is consequential for a client with several brokers. If it closes multiple idle connections, their combined absence should not become a claim that it attempted and failed to reach every broker. A count of closed transports and a count of observed failures answer different questions.

A successful connection invalidates older failure evidence

The second correction concerns cached down state. The release explains that the client may not need to connect to a particular broker for some time. A cached failure can therefore outlive the conditions under which it was observed.

Before the fix, that old state could contribute to an all-brokers-down error even though the client had not tried every broker since its last successful connection. The conclusion combined observations from different periods without requiring a fresh attempt.

Version 2.11.1 resets cached broker-down state when any broker connects successfully. Other brokers then need to be tried again before their failures can contribute to the same broad conclusion. The successful connection establishes a reason to reconsider the previous set of failure observations.

This does not prove that every broker is healthy. It changes the evidence required to report that all are down. A fresh successful connection and an old failed connection should not be treated as equivalent observations of the same moment.

The distinction is useful when interpreting application callbacks. The client reports what its state machine has established under its connection policy. A precise error requires that the bookkeeping match the intended claim, especially when a message refers to every known broker.

Incorrect reporting can trigger recovery work

The release notes connect false all-brokers-down states with automatic rebootstrap. Since 2.10.0, the incorrect state could also start a new bootstrap sequence. The patch therefore affects more than the wording of a log entry.

Rebootstrap returns to configured discovery addresses to find brokers again. That is useful when discovered metadata is stale, but unnecessary discovery can follow if the trigger merely reflects planned connection closure. Correcting the trigger avoids treating normal connection management as a reason to reset discovery.

The effect depends on the configured recovery behavior. The release does not claim that every false error caused data loss or that every rebootstrap attempt failed. Its concrete correction is to stop the wrong transitions and stale observations from producing that state.

My preference is for recovery actions to correspond to an identified failure. Kafka's replay capability gives consumers room to resume work, but needless rediscovery is still a different operation from continuing through an ordinary idle connection cycle.

Feature detection also stops depending on one old API version

The same maintenance release revises feature-enablement checks. Earlier checks matched a single RPC version rather than a supported range. Removing that old version in a newer broker could therefore disable a feature even when compatible versions remained.

The correction makes feature detection depend on the available range. That addresses a compatibility interpretation problem, separately from whether a TCP connection succeeds. A reachable broker can still be misclassified if the client asks the wrong capability question.

These changes share a precise concern with the meaning of observations. Planned closure does not mean failure, an old failure does not remain current forever, and absence of one RPC version does not necessarily mean absence of the feature. Version 2.11.1 repairs those interpretations in the native client's connection and capability state.