<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Apache ZooKeeper Operations Guides on Netdata</title><link>https://www.netdata.cloud/guides/zookeeper/</link><description>Recent content in Apache ZooKeeper Operations Guides on Netdata</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://www.netdata.cloud/guides/zookeeper/index.xml" rel="self" type="application/rss+xml"/><item><title>How ZooKeeper actually works in production: a mental model for operators</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-how-it-works-in-production/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-how-it-works-in-production/</guid><description>&lt;h1 id="how-zookeeper-actually-works-in-production-a-mental-model-for-operators">How ZooKeeper actually works in production: a mental model for operators&lt;/h1>
&lt;p>ZooKeeper is a distributed coordination service built on a replicated state machine. It maintains a hierarchical namespace of data nodes (znodes) entirely in memory and replicates every mutation across an ensemble of servers using the ZAB (ZooKeeper Atomic Broadcast) protocol.&lt;/p>
&lt;p>This is the mental model the rest of the ZooKeeper runbooks assume. It is the set of abstractions an on-call engineer needs to reason about why writes stall, sessions expire, a &amp;ldquo;healthy&amp;rdquo; node can return stale reads, and why the leader matters more than any other node in the cluster.&lt;/p></description></item><item><title>ZooKeeper "Cannot open channel to N at election address": the blocked election port</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-cannot-open-channel-at-election-address/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-cannot-open-channel-at-election-address/</guid><description>&lt;h1 id="zookeeper-cannot-open-channel-to-n-at-election-address-the-blocked-election-port">ZooKeeper &amp;ldquo;Cannot open channel to N at election address&amp;rdquo;: the blocked election port&lt;/h1>
&lt;p>The log line is &lt;code>Cannot open channel to &amp;lt;id&amp;gt; at election address /host:3888&lt;/code>. It is emitted by &lt;code>QuorumCnxManager.connectOne()&lt;/code> when &lt;code>Socket.connect()&lt;/code> to a peer&amp;rsquo;s leader election port fails with &lt;code>ConnectException&lt;/code> (refused) or &lt;code>SocketTimeoutException&lt;/code> (timed out). The error is harmless during steady state and fatal during an election.&lt;/p>
&lt;p>ZooKeeper ensembles use two inter-server TCP ports. Port 2888 (the quorum port) carries the ZAB proposal/ACK/commit stream between followers and the active leader. Port 3888 (the leader election port) is touched only when &lt;code>FastLeaderElection&lt;/code> needs pairwise TCP channels to every voting peer. If 2888 is reachable but 3888 is not, the ensemble runs fine until the leader is lost, at which point no new leader can be elected.&lt;/p></description></item><item><title>ZooKeeper "Client session timed out, have not heard from server": the heartbeat miss</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-client-session-timed-out/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-client-session-timed-out/</guid><description>&lt;h1 id="zookeeper-client-session-timed-out-have-not-heard-from-server-the-heartbeat-miss">ZooKeeper &amp;ldquo;Client session timed out, have not heard from server&amp;rdquo;: the heartbeat miss&lt;/h1>
&lt;p>A &lt;code>Client session timed out, have not heard from server in &amp;lt;ms&amp;gt;ms for session id 0x..., closing socket connection and attempting reconnect&lt;/code> log line is the client&amp;rsquo;s &lt;code>SendThread&lt;/code> reporting that no PING response arrived inside its heartbeat window. This is a client-side symptom of a heartbeat miss. It is not the server expiring the session, and it is not yet &lt;code>SessionExpired&lt;/code>. The client closes its socket and tries another ensemble member.&lt;/p></description></item><item><title>ZooKeeper "Detected pause in JVM or host machine (eg GC)": the pause-monitor warning</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-detected-pause-in-jvm/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-detected-pause-in-jvm/</guid><description>&lt;h1 id="zookeeper-detected-pause-in-jvm-or-host-machine-eg-gc-the-pause-monitor-warning">ZooKeeper &amp;ldquo;Detected pause in JVM or host machine (eg GC)&amp;rdquo;: the pause-monitor warning&lt;/h1>
&lt;p>The log line looks like this:&lt;/p>
&lt;pre>&lt;code>Detected pause in JVM or host machine (eg GC): pause of approximately 5234ms
&lt;/code>&lt;/pre>
&lt;p>ZooKeeper&amp;rsquo;s JvmPauseMonitor emits that line when the process froze longer than its configured threshold. The monitor thread sleeps for a fixed interval, wakes, and measures how long the sleep actually took. Anything beyond the expected sleep plus the warn threshold gets logged. If the JVM was not in a visible GC at that moment, the line ends with &amp;ldquo;No GCs detected&amp;rdquo;, which is the operator&amp;rsquo;s cue that something else on the host stole CPU.&lt;/p></description></item><item><title>ZooKeeper "fsync-ing the write ahead log took too long": the disk warning behind most write stalls</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-fsync-warning-adversely-affect-latency/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-fsync-warning-adversely-affect-latency/</guid><description>&lt;h1 id="zookeeper-fsync-ing-the-write-ahead-log-took-too-long-the-disk-warning-behind-most-write-stalls">ZooKeeper &amp;ldquo;fsync-ing the write ahead log took too long&amp;rdquo;: the disk warning behind most write stalls&lt;/h1>
&lt;p>The warning:&lt;/p>
&lt;pre tabindex="0">&lt;code>fsync-ing the write ahead log in SyncThread:0 took 1234ms which will adversely affect operation latency...
&lt;/code>&lt;/pre>&lt;p>fires when fsync on the transaction log exceeds &lt;code>fsync.warningthresholdms&lt;/code> (default 1000ms). The wording is deliberate: every write in ZooKeeper blocks on a quorum of fsyncs. If fsync takes a second, every write takes a second. If fsync takes 10 seconds, you are one missed heartbeat away from a leader election.&lt;/p></description></item><item><title>ZooKeeper "Packet len is out of range": jute.maxbuffer and oversized znodes</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-packet-len-out-of-range/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-packet-len-out-of-range/</guid><description>&lt;h1 id="zookeeper-packet-len-is-out-of-range-jutemaxbuffer-and-oversized-znodes">ZooKeeper &amp;ldquo;Packet len is out of range&amp;rdquo;: jute.maxbuffer and oversized znodes&lt;/h1>
&lt;p>&lt;code>Packet len &amp;lt;N&amp;gt; is out of range!&lt;/code> looks like a network framing problem. It is not. The ZooKeeper client is telling you the server&amp;rsquo;s serialized response exceeded the client&amp;rsquo;s maximum deserialization buffer, and the client closed the connection rather than read a truncated packet.&lt;/p>
&lt;p>On the server side, the same condition produces a terser log line: &lt;code>Len error&lt;/code>. That appears when a client attempts a write whose payload exceeds the server&amp;rsquo;s configured buffer limit. Both sides are governed by one Java system property: &lt;code>jute.maxbuffer&lt;/code>, which defaults to &lt;code>0xfffff&lt;/code> (1048575 bytes, just under 1 MB).&lt;/p></description></item><item><title>ZooKeeper "Too many connections from /IP - max is 60": maxClientCnxns rejecting clients</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-too-many-connections-max-is/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-too-many-connections-max-is/</guid><description>&lt;h1 id="zookeeper-too-many-connections-from-ip---max-is-60-maxclientcnxns-rejecting-clients">ZooKeeper &amp;ldquo;Too many connections from /IP - max is 60&amp;rdquo;: maxClientCnxns rejecting clients&lt;/h1>
&lt;p>&lt;code>WARN ... Error accepting new connection: Too many connections from /1.2.3.4 - max is 60&lt;/code> is ZooKeeper&amp;rsquo;s &lt;code>maxClientCnxns&lt;/code> limiter refusing a new TCP connection from a specific source IP. By the time it appears in the server log, the client has already been denied.&lt;/p>
&lt;p>The first trap: &lt;code>maxClientCnxns&lt;/code> is enforced per source IP, not as a total. A single ZooKeeper node can hold thousands of healthy sessions while still refusing every new connection from one IP. &lt;code>zk_num_alive_connections&lt;/code>, the metric most teams watch, is a total. It can look completely normal while clients behind a shared host IP are being silently turned away.&lt;/p></description></item><item><title>ZooKeeper "Unable to load database on disk": corrupt snapshot on startup</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-unable-to-load-database-on-disk/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-unable-to-load-database-on-disk/</guid><description>&lt;h1 id="zookeeper-unable-to-load-database-on-disk-corrupt-snapshot-on-startup">ZooKeeper &amp;ldquo;Unable to load database on disk&amp;rdquo;: corrupt snapshot on startup&lt;/h1>
&lt;p>The startup error &lt;code>Unable to load database on disk&lt;/code> from &lt;code>FileTxnSnapLog&lt;/code> means ZooKeeper cannot reconstruct its in-memory data tree from the on-disk snapshot and transaction log. The node refuses to join the ensemble and exits before serving traffic. You typically see this only on the next restart after the corruption happened, often days later.&lt;/p>
&lt;p>The failure is nasty because the running process looks fine until it does not. The corruption was already on disk; the restart made it impossible to ignore. A node that was serving requests an hour ago can refuse to come back after an unclean shutdown, an OOMKill, or a full &lt;code>dataDir&lt;/code> disk.&lt;/p></description></item><item><title>ZooKeeper "X is not executed because it is not in the whitelist": four-letter-word commands blocked</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-command-not-in-whitelist/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-command-not-in-whitelist/</guid><description>&lt;h1 id="zookeeper-x-is-not-executed-because-it-is-not-in-the-whitelist-four-letter-word-commands-blocked">ZooKeeper &amp;ldquo;X is not executed because it is not in the whitelist&amp;rdquo;: four-letter-word commands blocked&lt;/h1>
&lt;p>The error string is exact. When you run &lt;code>echo mntr | nc localhost 2181&lt;/code> against a ZooKeeper 3.5.3+ server that has not been configured for it, the server replies:&lt;/p>
&lt;pre tabindex="0">&lt;code>mntr is not executed because it is not in the whitelist.
&lt;/code>&lt;/pre>&lt;p>Same shape for &lt;code>ruok&lt;/code>, &lt;code>isro&lt;/code>, &lt;code>stat&lt;/code>, &lt;code>conf&lt;/code>, &lt;code>envi&lt;/code>, &lt;code>cons&lt;/code>, &lt;code>wchs&lt;/code>, and the rest of the four-letter-word (4lw) command set. Only &lt;code>srvr&lt;/code> works out of the box, because the bundled &lt;code>zkServer.sh&lt;/code> status check depends on it.&lt;/p></description></item><item><title>ZooKeeper authentication failures: SASL/Digest auth_failed_count climbing</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-auth-failed-count/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-auth-failed-count/</guid><description>&lt;h1 id="zookeeper-authentication-failures-sasldigest-auth_failed_count-climbing">ZooKeeper authentication failures: SASL/Digest auth_failed_count climbing&lt;/h1>
&lt;p>The &lt;code>zk_auth_failed_count&lt;/code> counter exposed by ZooKeeper&amp;rsquo;s &lt;code>mntr&lt;/code> four-letter command increments every time a client fails authentication under the Digest or SASL schemes. In a stable, locked-down production ensemble this counter is effectively flat between restarts. When it moves, a client is connecting with credentials the server rejects.&lt;/p>
&lt;p>The metric is per-server and cumulative since process start. It does not break out by auth scheme, source IP, or principal, so the counter alone tells you something is wrong but not who or why. You resolve the &amp;ldquo;who and why&amp;rdquo; by reading the ZooKeeper log, the surrounding metrics (&lt;code>zk_ensemble_auth_fail&lt;/code> &lt;!-- TODO: verify exact mntr name; ZooKeeper sources often expose `zk_ensemble_auth_failures` -->, &lt;code>zk_connection_rejected&lt;/code> &lt;!-- TODO: verify exact name -->), and the deployment timeline.&lt;/p></description></item><item><title>ZooKeeper autopurge not configured: snapshots and logs filling the disk over months</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-autopurge-not-configured/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-autopurge-not-configured/</guid><description>&lt;h1 id="zookeeper-autopurge-not-configured-snapshots-and-logs-filling-the-disk-over-months">ZooKeeper autopurge not configured: snapshots and logs filling the disk over months&lt;/h1>
&lt;p>&lt;code>autopurge.purgeInterval&lt;/code> defaults to &lt;code>0&lt;/code>, meaning snapshots and transaction logs accumulate forever. On a quiet ensemble the growth is slow enough that nobody notices for months, then the &lt;code>dataLogDir&lt;/code> partition hits 100%, ZooKeeper cannot fsync the next write, and the process dies. The leader throws an &lt;code>IOException&lt;/code> on the transaction log and the ensemble loses a member, or quorum if more than one node fills simultaneously.&lt;/p></description></item><item><title>ZooKeeper avg_latency hides write stalls: why the headline number lies</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-avg-latency-hiding-write-stalls/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-avg-latency-hiding-write-stalls/</guid><description>&lt;h1 id="zookeeper-avg_latency-hides-write-stalls-why-the-headline-number-lies">ZooKeeper avg_latency hides write stalls: why the headline number lies&lt;/h1>
&lt;p>The dashboard says &lt;code>zk_avg_latency&lt;/code> is 1.2 ms. Clients are timing out on writes. Both can be true. On a read-heavy ZooKeeper ensemble, the headline latency number can look healthy while the write path is stalled.&lt;/p>
&lt;p>Two properties cause this. First, &lt;code>zk_avg_latency&lt;/code>, &lt;code>zk_min_latency&lt;/code>, and &lt;code>zk_max_latency&lt;/code> aggregate reads and writes into one number. Reads are served from local memory and complete in microseconds. Writes require a quorum round-trip plus a transaction log fsync before acknowledgment. When reads dominate the request mix, a severe write stall is diluted by thousands of cheap reads and disappears into the average.&lt;/p></description></item><item><title>ZooKeeper connection drops spiking: sessions dying in bursts</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-connection-drop-spike/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-connection-drop-spike/</guid><description>&lt;h1 id="zookeeper-connection-drops-spiking-sessions-dying-in-bursts">ZooKeeper connection drops spiking: sessions dying in bursts&lt;/h1>
&lt;p>A burst in &lt;code>zk_connection_drop_count&lt;/code> means connections to a ZooKeeper server are closing in a tight window, not one at a time. When the burst pushes &lt;code>zk_stale_sessions_expired&lt;/code> up simultaneously, you are looking at a session expiration storm in progress or one about to land on dependent services.&lt;/p>
&lt;p>Occasional single drops across a large fleet are background noise. A sustained drop rate above roughly 0.1% of total connections per minute is where the signal stops being normal churn. Bursts that fire on a rhythm (every few minutes, hourly, at the same minute past the hour) almost always point to a JVM garbage collection cycle or a scheduled job that briefly saturates the leader.&lt;/p></description></item><item><title>ZooKeeper data size growing: using ZooKeeper as a database is an anti-pattern</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-approximate-data-size-growing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-approximate-data-size-growing/</guid><description>&lt;h1 id="zookeeper-data-size-growing-using-zookeeper-as-a-database-is-an-anti-pattern">ZooKeeper data size growing: using ZooKeeper as a database is an anti-pattern&lt;/h1>
&lt;p>ZooKeeper is a distributed coordination service, not a datastore. It holds the entire znode tree in JVM heap, replicates every mutation through ZAB, and periodically serializes the full tree to a snapshot on disk. The design point is small, hot, strongly consistent metadata: leader election handles, service discovery registrations, distributed locks, configuration pointers. When teams treat it as a general-purpose key-value store and let &lt;code>zk_approximate_data_size&lt;/code> climb, they inherit the operational characteristics of an in-memory database without the tooling, schema, or compaction strategies of one.&lt;/p></description></item><item><title>ZooKeeper data tree digest mismatch: detecting corruption before it spreads</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-digest-mismatch/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-digest-mismatch/</guid><description>&lt;h1 id="zookeeper-data-tree-digest-mismatch-detecting-corruption-before-it-spreads">ZooKeeper data tree digest mismatch: detecting corruption before it spreads&lt;/h1>
&lt;p>When &lt;code>zk_digest_mismatches_count&lt;/code> increments on a ZooKeeper node, the in-memory data tree on that node has diverged from the checksum ZooKeeper expects. This is a data-integrity alarm, not a performance signal. Clients reading from that node may be receiving wrong answers, and if the divergence came from a ZAB replication bug rather than local corruption, the same divergence may be propagating to other ensemble members.&lt;/p></description></item><item><title>ZooKeeper dataLogDir sharing a disk with snapshots: the #1 fsync-latency footgun</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-datalogdir-not-separated/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-datalogdir-not-separated/</guid><description>&lt;h1 id="zookeeper-datalogdir-sharing-a-disk-with-snapshots-the-1-fsync-latency-footgun">ZooKeeper dataLogDir sharing a disk with snapshots: the #1 fsync-latency footgun&lt;/h1>
&lt;p>You are chasing intermittent ZooKeeper write-latency spikes that appear to have no cause. Average latency is fine most of the time. Then, every few minutes, p99 update latency jumps by an order of magnitude, &lt;code>zk_outstanding_requests&lt;/code> briefly climbs, and clients on tight timeouts see a flicker of connection churn. By the time you SSH in, the cluster looks healthy again.&lt;/p></description></item><item><title>ZooKeeper follower doing a SNAP sync: full snapshot transfer and its blast radius</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-follower-snap-sync/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-follower-snap-sync/</guid><description>&lt;h1 id="zookeeper-follower-doing-a-snap-sync-full-snapshot-transfer-and-its-blast-radius">ZooKeeper follower doing a SNAP sync: full snapshot transfer and its blast radius&lt;/h1>
&lt;p>A follower that fell too far behind the leader does not catch up transaction by transaction. Once its last-seen zxid is older than the leader&amp;rsquo;s retained transaction log, the leader ships the entire data tree as a snapshot. This is a SNAP sync, the most expensive recovery path a healthy ensemble runs short of a leader election.&lt;/p></description></item><item><title>ZooKeeper follower sync time climbing: a follower approaching ejection</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-follower-sync-time-high/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-follower-sync-time-high/</guid><description>&lt;h1 id="zookeeper-follower-sync-time-climbing-a-follower-approaching-ejection">ZooKeeper follower sync time climbing: a follower approaching ejection&lt;/h1>
&lt;p>When &lt;code>zk_avg_follower_sync_time&lt;/code> or &lt;code>zk_max_follower_sync_time&lt;/code> starts climbing, a follower is taking longer to process proposals from the leader. The metric measures how close a follower is to being ejected from the quorum.&lt;/p>
&lt;p>The hard ceiling is &lt;code>syncLimit x tickTime&lt;/code>. With defaults of &lt;code>syncLimit=5&lt;/code> and &lt;code>tickTime=2000ms&lt;/code>, that ceiling is 10 seconds. When a follower&amp;rsquo;s sync time approaches that limit, the leader closes the connection, stops pushing updates, and the follower must re-enter leader discovery. In a 3-node ensemble, that drops you to minimum quorum with zero remaining fault tolerance.&lt;/p></description></item><item><title>ZooKeeper GC pause cascade: how a Stop-the-World freeze expires sessions and re-elects the leader</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-gc-pause-cascade/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-gc-pause-cascade/</guid><description>&lt;h1 id="zookeeper-gc-pause-cascade-how-a-stop-the-world-freeze-expires-sessions-and-re-elects-the-leader">ZooKeeper GC pause cascade: how a Stop-the-World freeze expires sessions and re-elects the leader&lt;/h1>
&lt;p>A ZooKeeper ensemble loses connections in bursts. Sessions expire en masse. The leader changes without a network cause. Request latency spikes on a rhythm that does not match disk I/O. The cause is usually a JVM Stop-the-World pause, and the fix is on the JVM, not the network.&lt;/p>
&lt;p>The mechanism: a JVM STW pause freezes the entire ZooKeeper process. No heartbeats go out. No requests are processed. No quorum ACKs flow. The TCP listener still accepts sockets, so the server looks alive from the outside, but the process does nothing with them. Clients miss their heartbeat window and their sessions expire. Followers miss the leader&amp;rsquo;s heartbeat and, if the pause runs past &lt;code>syncLimit * tickTime&lt;/code> (default 10 seconds with &lt;code>tickTime=2000&lt;/code> and &lt;code>syncLimit=5&lt;/code>), they declare the leader dead and start a new election. When the JVM resumes, the queued backlog drains as a latency spike and disconnected clients reconnect in a herd.&lt;/p></description></item><item><title>ZooKeeper heap usage climbing: catching the GC death spiral before it starts</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-heap-pressure-climbing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-heap-pressure-climbing/</guid><description>&lt;h1 id="zookeeper-heap-usage-climbing-catching-the-gc-death-spiral-before-it-starts">ZooKeeper heap usage climbing: catching the GC death spiral before it starts&lt;/h1>
&lt;p>ZooKeeper keeps its entire data tree on the JVM heap: every znode, its data bytes, ACLs, children lists, watch registrations, and session state. When heap climbs, it is the leading indicator for the OOM that eventually kills the ensemble. The signal that matters is not the sawtooth peaks from young-generation GC, but the rising post-GC trough that means the live set itself is growing.&lt;/p></description></item><item><title>ZooKeeper KeeperErrorCode = ConnectionLoss: the transient disconnect every client hits</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-connectionloss/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-connectionloss/</guid><description>&lt;h1 id="zookeeper-keepererrorcode--connectionloss-the-transient-disconnect-every-client-hits">ZooKeeper KeeperErrorCode = ConnectionLoss: the transient disconnect every client hits&lt;/h1>
&lt;p>&lt;code>KeeperErrorCode = ConnectionLoss&lt;/code> is the error every ZooKeeper client eventually logs. It means the TCP connection between the client and the server it was talking to broke before the operation&amp;rsquo;s response arrived. It does not mean the operation failed, and it does not mean the session is gone. The outcome of the in-flight operation is unknown, and the correct response is an idempotent retry.&lt;/p></description></item><item><title>ZooKeeper KeeperErrorCode = NoAuth: ACL denials on protected znodes</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-noauth-error/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-noauth-error/</guid><description>&lt;h1 id="zookeeper-keepererrorcode--noauth-acl-denials-on-protected-znodes">ZooKeeper KeeperErrorCode = NoAuth: ACL denials on protected znodes&lt;/h1>
&lt;p>&lt;code>KeeperErrorCode = NoAuth for /path&lt;/code> appears in client logs when a ZooKeeper operation is rejected because the calling session lacks the ACL permission required for that operation on that znode. The matching server-side line is &lt;code>Permission denied&lt;/code>. This is not a transient connectivity issue. The request reached a server, the server evaluated the znode&amp;rsquo;s ACL, and the session did not match.&lt;/p></description></item><item><title>ZooKeeper KeeperErrorCode = NodeExists: create failing on an already-created znode</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-nodeexists-error/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-nodeexists-error/</guid><description>&lt;h1 id="zookeeper-keepererrorcode--nodeexists-create-failing-on-an-already-created-znode">ZooKeeper KeeperErrorCode = NodeExists: create failing on an already-created znode&lt;/h1>
&lt;p>The error:&lt;/p>
&lt;pre tabindex="0">&lt;code>org.apache.zookeeper.KeeperException$NodeExistsException: KeeperErrorCode = NodeExists for /some/path
&lt;/code>&lt;/pre>&lt;p>A &lt;code>create()&lt;/code> hit a znode path that already exists. ZooKeeper classifies this as a state exception, not a system fault. The cluster refused to overwrite an existing node, exactly as specified. The question is whether the caller expected that path to be free.&lt;/p>
&lt;p>Most production hits follow one of two patterns. The first is a retry after &lt;code>ConnectionLoss&lt;/code>: the original &lt;code>create()&lt;/code> committed but the response was lost in flight. The client does not know whether the operation succeeded, retries, and receives &lt;code>NodeExists&lt;/code>. The second is a genuine race: two candidates trying to create the same ephemeral leader or lock node, where exactly one wins and the other should lose gracefully. Both are expected. The incident starts when a client mishandles the exception, or when an orphaned ephemeral blocks the legitimate owner indefinitely.&lt;/p></description></item><item><title>ZooKeeper KeeperErrorCode = NoNode: operating on a path that doesn't exist</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-nonode-error/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-nonode-error/</guid><description>&lt;h1 id="zookeeper-keepererrorcode--nonode-operating-on-a-path-that-doesnt-exist">ZooKeeper KeeperErrorCode = NoNode: operating on a path that doesn&amp;rsquo;t exist&lt;/h1>
&lt;p>A client logs &lt;code>KeeperErrorCode = NoNode for /some/path&lt;/code>. The server returned &lt;code>Code.NONODE&lt;/code> (integer -101), which the Java client surfaces as &lt;code>KeeperException.NoNodeException&lt;/code>. The failed operation was a &lt;code>getData&lt;/code>, &lt;code>getChildren&lt;/code>, &lt;code>exists&lt;/code>, &lt;code>setData&lt;/code>, &lt;code>delete&lt;/code>, or &lt;code>create&lt;/code> against a znode that is not currently in the data tree.&lt;/p>
&lt;p>&lt;code>NoNode&lt;/code> is not a server fault. It is the API contract enforced correctly: ZooKeeper refuses to operate on a missing path. The operator&amp;rsquo;s job is to find out why the path is missing. Three cases cover almost every incident: the path was never created (usually a missing parent), the path was deleted by the server (an ephemeral tied to an expired session, or a container/TTL node auto-cleaned), or a deploy changed the znode layout clients expect.&lt;/p></description></item><item><title>ZooKeeper KeeperErrorCode = Session expired: ephemeral nodes gone, clients evicted</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-session-expired/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-session-expired/</guid><description>&lt;h1 id="zookeeper-keepererrorcode--session-expired-ephemeral-nodes-gone-clients-evicted">ZooKeeper KeeperErrorCode = Session expired: ephemeral nodes gone, clients evicted&lt;/h1>
&lt;p>The exact error clients log is &lt;code>KeeperErrorCode = Session expired&lt;/code>. On the ZooKeeper side you see &lt;code>Expiring session 0x... timeout of Nms exceeded&lt;/code>. Once that line lands, the client&amp;rsquo;s ZooKeeper handle is dead and every piece of state it owned through that session is gone: ephemeral znodes deleted, watches invalidated, ACLs no longer enforceable. The client cannot reconnect on the same handle. It must build a new ZooKeeper object, negotiate a new session, and recreate every ephemeral node it relied on.&lt;/p></description></item><item><title>ZooKeeper leader election storm: an ensemble that keeps re-electing</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-leader-election-storm/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-leader-election-storm/</guid><description>&lt;h1 id="zookeeper-leader-election-storm-an-ensemble-that-keeps-re-electing">ZooKeeper leader election storm: an ensemble that keeps re-electing&lt;/h1>
&lt;p>&lt;code>zk_looking_count&lt;/code> is incrementing on multiple nodes. The ZooKeeper log fills with repeated &lt;code>LEADING&lt;/code> and &lt;code>FOLLOWING&lt;/code> transitions. Every few seconds or minutes, the ensemble elects a new leader, and that leader quickly loses quorum. Writes are intermittent, and downstream systems that depend on ZooKeeper for coordination (Kafka controllers, HBase region assignment, distributed locks) experience cascading failures.&lt;/p>
&lt;p>This is a leader election storm. Unlike a single failover where remaining nodes elect a stable replacement, here every potential leader hits the same wall. The root cause is shared across ensemble members: fsync stalls on overloaded storage, GC pauses exceeding the quorum timeout, or intermittent network failures between server pairs. Because every candidate experiences the same problem, no leader holds the role long enough for the cluster to recover.&lt;/p></description></item><item><title>ZooKeeper monitoring checklist: the signals every production ensemble needs</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-monitoring-checklist/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-monitoring-checklist/</guid><description>&lt;h1 id="zookeeper-monitoring-checklist-the-signals-every-production-ensemble-needs">ZooKeeper monitoring checklist: the signals every production ensemble needs&lt;/h1>
&lt;p>A reference checklist for engineers running production ZooKeeper ensembles. Signals are organized into four maturity levels: survival, operational, mature, and expert. Each level adds visibility for failure modes the previous level cannot see.&lt;/p>
&lt;p>The levels are cumulative. Level 2 assumes Level 1 is covered. Skipping to Level 4 without Levels 1 through 3 leaves gaps in the signals that actually page you during incidents: disk stalls, GC cascades, and quorum loss.&lt;/p></description></item><item><title>ZooKeeper monitoring maturity model: from survival to expert</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-monitoring-maturity-model/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-monitoring-maturity-model/</guid><description>&lt;h1 id="zookeeper-monitoring-maturity-model-from-survival-to-expert">ZooKeeper monitoring maturity model: from survival to expert&lt;/h1>
&lt;p>Most ZooKeeper monitoring stops too early. Teams run &lt;code>ruok&lt;/code> as their only health check, collect &lt;code>zk_avg_latency&lt;/code> without understanding it is cumulative since the last reset, and never look at fsync latency until a write stall cascades into a Kafka outage. The ensemble looks healthy in dashboards until it suddenly does not, and the postmortem reveals the signals were there all along, uncollected.&lt;/p></description></item><item><title>ZooKeeper OutOfMemoryError: Java heap space - the OOM that kills the whole ensemble at once</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-heap-exhaustion-oom/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-heap-exhaustion-oom/</guid><description>&lt;h1 id="zookeeper-outofmemoryerror-java-heap-space---the-oom-that-kills-the-whole-ensemble-at-once">ZooKeeper OutOfMemoryError: Java heap space - the OOM that kills the whole ensemble at once&lt;/h1>
&lt;p>You grep the ZooKeeper log and find &lt;code>java.lang.OutOfMemoryError: Java heap space&lt;/code>. The process is gone. A minute later another node dies with the same error, then the third. The whole ensemble went down inside a single window, not as a rolling failure. That simultaneity is the signature, not a cascade.&lt;/p>
&lt;p>ZooKeeper holds the entire data tree on the JVM heap: every znode, its data, ACL references, children lists, stat structures, plus session state, watch tables, and request queues. Every ensemble member holds the same tree. Whatever fills the heap on one node fills it on all of them at roughly the same rate, so when the tree finally exceeds the heap they OOM near-simultaneously. This is a single-cause total outage.&lt;/p></description></item><item><title>ZooKeeper outstanding requests growing: the request pipeline is backing up</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-outstanding-requests-growing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-outstanding-requests-growing/</guid><description>&lt;h1 id="zookeeper-outstanding-requests-growing-the-request-pipeline-is-backing-up">ZooKeeper outstanding requests growing: the request pipeline is backing up&lt;/h1>
&lt;p>&lt;code>zk_outstanding_requests&lt;/code> counts requests queued in the server&amp;rsquo;s request processor pipeline that have not yet completed. In steady state it sits at or near zero. When it climbs, something downstream in the pipeline has stopped draining faster than clients are submitting.&lt;/p>
&lt;p>The queue is a leading indicator. Requests pile up before &lt;code>zk_avg_latency&lt;/code> reacts, and well before the server starts dropping client traffic. If you wait for latency alerts, you have already lost the lead time needed to keep dependent services like Kafka, HBase, and Solr from feeling the stall.&lt;/p></description></item><item><title>ZooKeeper pending syncs growing: followers can't keep up with the write rate</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-pending-syncs-growing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-pending-syncs-growing/</guid><description>&lt;h1 id="zookeeper-pending-syncs-growing-followers-cant-keep-up-with-the-write-rate">ZooKeeper pending syncs growing: followers can&amp;rsquo;t keep up with the write rate&lt;/h1>
&lt;p>&lt;code>zk_pending_syncs&lt;/code> is the leader&amp;rsquo;s count of in-flight sync operations to followers. In steady state it sits at zero. Sustained non-zero values mean at least one follower cannot absorb the proposal stream as fast as the leader generates it. This is ZooKeeper&amp;rsquo;s replication-lag signal, distinct from generic latency metrics because it points directly at the write pipeline&amp;rsquo;s fan-out side.&lt;/p></description></item><item><title>ZooKeeper proposals not committing: proposal_count outpacing commit_count</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-proposal-commit-divergence/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-proposal-commit-divergence/</guid><description>&lt;h1 id="zookeeper-proposals-not-committing-proposal_count-outpacing-commit_count">ZooKeeper proposals not committing: proposal_count outpacing commit_count&lt;/h1>
&lt;p>In a healthy ZooKeeper ensemble, every proposal the leader broadcasts is committed a few milliseconds later, after a quorum of followers acknowledges it. The two counters &lt;code>zk_proposal_count&lt;/code> and &lt;code>zk_commit_count&lt;/code> track the front and back of that pipeline, and on a cluster with active writers their rates should track each other closely.&lt;/p>
&lt;p>When &lt;code>zk_proposal_count&lt;/code> keeps climbing but &lt;code>zk_commit_count&lt;/code> stalls, the leader is generating proposals but cannot reach quorum ACK. Writes are not landing. Clients with operation timeouts start failing, ephemeral nodes are not being created, and dependent systems (Kafka controller, HBase master, Solr overseer) start logging &amp;ldquo;operation timeout&amp;rdquo; or &amp;ldquo;session expired&amp;rdquo;. A worse signal is both metrics staying flat while writers are active: the write pipeline is fully blocked, or the leader is isolated from the quorum.&lt;/p></description></item><item><title>ZooKeeper quorum ack latency high: followers slow to acknowledge proposals</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-quorum-ack-latency-high/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-quorum-ack-latency-high/</guid><description>&lt;h1 id="zookeeper-quorum-ack-latency-high-followers-slow-to-acknowledge-proposals">ZooKeeper quorum ack latency high: followers slow to acknowledge proposals&lt;/h1>
&lt;p>&lt;code>zk_p99_quorum_ack_latency&lt;/code> is climbing on the leader and every write in the ensemble is paying for it. This metric measures the time from the leader sending a PROPOSE message to receiving quorum acknowledgments from followers. It is a leader-only signal.&lt;/p>
&lt;!-- TODO: verify availability. quorum_ack_latency and its percentile variants require the new metrics framework (3.6+). On older versions the metric will not exist. -->
&lt;p>Every ZooKeeper write blocks until a quorum of followers ACK. An ACK means the follower has written the proposal to its transaction log and fsync&amp;rsquo;d it to persistent storage. So quorum ack latency bundles two things into one number: the inter-node network round trip, and the follower&amp;rsquo;s fsync plus processing time. When this metric is elevated, the slowest follower in the quorum is bottlenecking writes for every client connected to the ensemble.&lt;/p></description></item><item><title>ZooKeeper quorum loss: no leader elected and every write is failing</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-quorum-loss-no-writes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-quorum-loss-no-writes/</guid><description>&lt;h1 id="zookeeper-quorum-loss-no-leader-elected-and-every-write-is-failing">ZooKeeper quorum loss: no leader elected and every write is failing&lt;/h1>
&lt;p>Every write to your ZooKeeper ensemble is timing out. Clients report &lt;code>ConnectionLoss&lt;/code> and &lt;code>SessionExpired&lt;/code>. Downstream systems that depend on ZK for coordination, such as Kafka controller elections or HBase region assignment, are cascading into failure. On the surviving ZK nodes, &lt;code>ruok&lt;/code> still returns &lt;code>imok&lt;/code>. The process is alive; the ensemble is not.&lt;/p>
&lt;p>Quorum loss is ZooKeeper&amp;rsquo;s worst-case availability scenario. When fewer than &lt;code>floor(N/2)+1&lt;/code> voting members can communicate, no leader can be elected and every write fails. Surviving nodes sit in &lt;code>LOOKING&lt;/code> state, unable to make progress through ZAB.&lt;/p></description></item><item><title>ZooKeeper read latency high: memory reads that should never be slow</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-read-latency-high/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-read-latency-high/</guid><description>&lt;h1 id="zookeeper-read-latency-high-memory-reads-that-should-never-be-slow">ZooKeeper read latency high: memory reads that should never be slow&lt;/h1>
&lt;p>Reads in ZooKeeper are local heap lookups. A &lt;code>getData&lt;/code>, &lt;code>getChildren&lt;/code>, or &lt;code>exists&lt;/code> call should return in well under a millisecond because no quorum is involved. The connected server walks its in-memory data tree and replies. When &lt;code>zk_p99_readlatency&lt;/code> sits above 50ms for minutes at a time, something on that JVM is competing with request processing.&lt;/p>
&lt;p>Do not treat read latency like write latency. Write latency is dominated by transaction-log fsync and quorum ACK. Read latency has none of that machinery, so when it climbs the cause is almost always local: a Stop-the-World GC pause, a pathologically deep or wide znode tree pushing heap pressure, or a watch-delivery backlog stealing CPU from the request thread. Correlating &lt;code>zk_p99_readlatency&lt;/code> with &lt;code>zk_jvm_pause_time_ms&lt;/code>, &lt;code>zk_znode_count&lt;/code>, and &lt;code>zk_watch_count&lt;/code> is what separates a 30-second diagnosis from an hour of guessing.&lt;/p></description></item><item><title>ZooKeeper request throttling: globalOutstandingLimit and TCP backpressure</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-throttled-ops-global-outstanding-limit/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-throttled-ops-global-outstanding-limit/</guid><description>&lt;h1 id="zookeeper-request-throttling-globaloutstandinglimit-and-tcp-backpressure">ZooKeeper request throttling: globalOutstandingLimit and TCP backpressure&lt;/h1>
&lt;p>&lt;code>zk_throttled_ops&lt;/code> incrementing in production is a saturation alarm, not a tuning knob. By the time this counter moves, the request pipeline is already full: the server has stopped reading from client sockets because the global outstanding request queue has reached &lt;code>globalOutstandingLimit&lt;/code> (default 1000), TCP backpressure is propagating to every connected client, and any client that cannot absorb the added latency is on its way to a session expiration.&lt;/p></description></item><item><title>ZooKeeper server stuck in LOOKING: a node that never rejoins the quorum</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-server-stuck-looking/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-server-stuck-looking/</guid><description>&lt;p>A single ZooKeeper node sits in LOOKING long after the ensemble has settled, or flaps between LOOKING and FOLLOWING. The rest of the ensemble holds a stable leader with healthy write throughput. Restart the orphaned node and it drops back into LOOKING. Restart the leader and it briefly rejoins, then falls out again.&lt;/p>
&lt;p>This is not quorum loss. Quorum loss is every node entering LOOKING at once because no majority can form. That case is covered in &lt;a href="https://www.netdata.cloud/guides/zookeeper/zookeeper-quorum-loss-no-writes/">ZooKeeper quorum loss: no leader elected and every write is failing&lt;/a>. This article covers the narrower symptom: one permanently-orphaned node while the rest of the ensemble serves traffic.&lt;/p></description></item><item><title>ZooKeeper session count climbing: leaks and duplicate sessions</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-session-count-climbing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-session-count-climbing/</guid><description>&lt;h1 id="zookeeper-session-count-climbing-leaks-and-duplicate-sessions">ZooKeeper session count climbing: leaks and duplicate sessions&lt;/h1>
&lt;p>&lt;code>zk_global_sessions&lt;/code> climbing while your client fleet is stable is a slow ZooKeeper failure mode. The ensemble keeps serving reads and writes, latency looks fine, quorum is intact, but the session table keeps growing. Each entry costs heap and periodic heartbeat processing. Eventually you hit a GC death spiral, an OOM, or a &lt;code>maxClientCnxns&lt;/code>-shaped outage.&lt;/p>
&lt;p>The signal is simple to read but easy to misinterpret. ZooKeeper exposes two distinct populations: global sessions, which the leader echoes across the ensemble, and local sessions (only present when &lt;code>localSessionsEnabled=true&lt;/code>, added in ZK 3.5, default &lt;code>false&lt;/code>), which live on a single follower and upgrade to global when the client creates an ephemeral node. If you only watch &lt;code>zk_global_sessions&lt;/code> you may be looking at a subset of the actual session population, and if you only watch &lt;code>zk_num_alive_connections&lt;/code> you cannot tell a leak from a deployment event.&lt;/p></description></item><item><title>ZooKeeper session expiration storm: the ephemeral-node thundering herd</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-session-expiration-storm/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-session-expiration-storm/</guid><description>&lt;h1 id="zookeeper-session-expiration-storm-the-ephemeral-node-thundering-herd">ZooKeeper session expiration storm: the ephemeral-node thundering herd&lt;/h1>
&lt;p>A session expiration storm is the worst-case thundering herd in a coordination service. Many clients lose contact long enough for the ensemble to declare their sessions dead. The cluster then deletes every ephemeral node owned by those sessions and fires every watch attached to those nodes. Every disconnected client reconnects at the same time, recreates its ephemeral nodes, and re-registers watches, hammering an ensemble that is already stressed.&lt;/p></description></item><item><title>ZooKeeper slow startup: snapshot load and txnlog replay taking minutes</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-slow-recovery-on-restart/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-slow-recovery-on-restart/</guid><description>&lt;h1 id="zookeeper-slow-startup-snapshot-load-and-txnlog-replay-taking-minutes">ZooKeeper slow startup: snapshot load and txnlog replay taking minutes&lt;/h1>
&lt;p>A ZooKeeper node you just restarted is not answering client requests. The process is up, the port is listening, but &lt;code>mntr&lt;/code> hangs or returns nothing useful, and dependent services are logging connection failures and session timeouts. Your dashboard shows &lt;code>zk_uptime&lt;/code> climbing past one, two, five minutes with no leader participation, or your health checks have already paged because the node looks dead.&lt;/p></description></item><item><title>ZooKeeper snapshot errors: recovery safety at risk</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-snapshot-errors/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-snapshot-errors/</guid><description>&lt;h1 id="zookeeper-snapshot-errors-recovery-safety-at-risk">ZooKeeper snapshot errors: recovery safety at risk&lt;/h1>
&lt;p>&lt;code>zk_snapshot_error_count&lt;/code> increments when ZooKeeper fails to serialize the in-memory data tree to disk, or fails to load a snapshot during startup. The node keeps serving reads and writes from its in-memory copy. The cost shows up on the next restart, when recovery cannot find a usable snapshot and either fails outright or replays stale state.&lt;/p>
&lt;p>A single increment is often transient. A backup job, a brief disk-full condition, or I/O contention from a colocated batch process can cause one snapshot to fail. The next snapshot cycle (taken every &lt;code>snapCount&lt;/code> transactions, default 100,000) succeeds and silently recovers. If you page on every increment, you burn through your team&amp;rsquo;s attention on events that self-resolve.&lt;/p></description></item><item><title>ZooKeeper split-brain: two nodes both reporting leader</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-split-brain-two-leaders/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-split-brain-two-leaders/</guid><description>&lt;h1 id="zookeeper-split-brain-two-nodes-both-reporting-leader">ZooKeeper split-brain: two nodes both reporting leader&lt;/h1>
&lt;p>Your monitoring polls each ZooKeeper node independently and two of them return &lt;code>zk_server_state leader&lt;/code>. Two servers in the same ensemble both believe they are the active leader. Treat this as an unconditional page: each side can accept writes that diverge from the other.&lt;/p>
&lt;p>ZAB (ZooKeeper Atomic Broadcast) is designed to make sustained split-brain impossible. A leader only becomes durable after a quorum of followers (floor(N/2)+1) has acknowledged the NEW_LEADER proposal. In a clean partition, the minority side cannot reach quorum and must block writes. So when two nodes both report leader for more than a brief convergence window, something has broken the quorum accounting: an asymmetric partition, a disk-full recovery bug, an authentication bypass, or a stale-read protocol corner case.&lt;/p></description></item><item><title>ZooKeeper stale reads from followers: zxid lag and read-after-write surprises</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-stale-reads-follower-lag/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-stale-reads-follower-lag/</guid><description>&lt;h1 id="zookeeper-stale-reads-from-followers-zxid-lag-and-read-after-write-surprises">ZooKeeper stale reads from followers: zxid lag and read-after-write surprises&lt;/h1>
&lt;p>A follower can pass every standard health check, serve reads at sub-millisecond latency, and still return data dozens of transactions behind what the leader just committed. No error is logged. No alert fires. The ensemble reports a leader, all followers are synced, and quorum is intact.&lt;/p>
&lt;p>This is not a bug. ZooKeeper offers sequential consistency for reads, not linearizability. Reads are served locally from each server&amp;rsquo;s in-memory data tree, and that tree may lag behind the leader&amp;rsquo;s committed state by anywhere from a few transactions to far more under load. For configuration data or service discovery where eventual consistency is tolerable, this is fine. For distributed locks, leader election fencing, or read-after-write logic, it can cause duplicate work, lock violations, or lost updates.&lt;/p></description></item><item><title>ZooKeeper stale requests dropped: requests aging out of the pipeline</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-stale-requests-dropped/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-stale-requests-dropped/</guid><description>&lt;h1 id="zookeeper-stale-requests-dropped-requests-aging-out-of-the-pipeline">ZooKeeper stale requests dropped: requests aging out of the pipeline&lt;/h1>
&lt;p>&lt;code>zk_stale_requests_dropped&lt;/code> incrementing is a late signal in a ZooKeeper saturation cascade. By the time a request ages out of the pipeline and is dropped, the server has already exhausted queue headroom, engaged throttling, and held the request long enough that the client gave up or the connection died. Treat any non-zero rate as an incident, and treat it as proof that an earlier signal was missed.&lt;/p></description></item><item><title>ZooKeeper synced_followers below ensemble size: degraded fault tolerance</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-synced-followers-degraded/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-synced-followers-degraded/</guid><description>&lt;h1 id="zookeeper-synced_followers-below-ensemble-size-degraded-fault-tolerance">ZooKeeper synced_followers below ensemble size: degraded fault tolerance&lt;/h1>
&lt;p>&lt;code>zk_synced_followers&lt;/code> reports how many followers are currently synced with the leader. In a healthy ensemble it equals &lt;code>ensemble_size - 1&lt;/code> (voting members only; observers are excluded). When it drops, a follower is disconnected or lagging, and your fault tolerance margin has shrunk.&lt;/p>
&lt;p>This metric is emitted only by the leader. Followers, observers, and standalone nodes do not report it. If your collector scrapes a fixed node or only followers, you have a blind spot: identify the leader dynamically, or scrape every node and keep only the values from the node reporting &lt;code>leader&lt;/code> in &lt;code>zk_server_state&lt;/code>.&lt;/p></description></item><item><title>ZooKeeper TLS handshake failures: unsuccessful handshakes and non-mTLS connections</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-tls-handshake-failures/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-tls-handshake-failures/</guid><description>&lt;h1 id="zookeeper-tls-handshake-failures-unsuccessful-handshakes-and-non-mtls-connections">ZooKeeper TLS handshake failures: unsuccessful handshakes and non-mTLS connections&lt;/h1>
&lt;p>When ZooKeeper is configured for TLS, the TLS layer becomes a new failure surface between clients and the ensemble. A spike in &lt;code>zk_unsuccessful_handshake&lt;/code> or &lt;code>zk_tls_handshake_exceeded&lt;/code> means clients are attempting TLS connections that never complete. If your environment requires mutual TLS, any non-zero value in &lt;code>zk_non_mtls_remote_conn_count&lt;/code> means a client bypassed mTLS entirely.&lt;/p>
&lt;p>These failures are noisy in a particular way. The client sees a connection timeout or a refused handshake, while the server logs an &amp;ldquo;Unsuccessful handshake&amp;rdquo; entry that does not always explain why. Certificate expiry, cipher mismatch, hostname verification failure, and low host entropy all produce similar surface symptoms. The fix is rarely the server itself; it is usually a client configuration error, an expired credential, or a monitoring tool sending plaintext to a secure port.&lt;/p></description></item><item><title>ZooKeeper transaction log disk full: the crash with no graceful degradation</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-disk-full-txnlog/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-disk-full-txnlog/</guid><description>&lt;h1 id="zookeeper-transaction-log-disk-full-the-crash-with-no-graceful-degradation">ZooKeeper transaction log disk full: the crash with no graceful degradation&lt;/h1>
&lt;p>ZooKeeper has no graceful degradation path for a full &lt;code>dataLogDir&lt;/code> partition. When the WAL append fails, the server throws an IOException and dies. There is no read-only fallback, no throttling, and no &lt;code>mntr&lt;/code> warning that precedes the crash. The same applies to the snapshot directory when the next snapshot write or pre-allocation fails.&lt;/p>
&lt;p>The most common root cause is broken or disabled autopurge. With &lt;code>autopurge.purgeInterval&lt;/code> defaulting to &lt;code>0&lt;/code> (disabled) and &lt;code>autopurge.snapRetainCount&lt;/code> defaulting to &lt;code>3&lt;/code>, an ensemble that has never been explicitly configured will accumulate transaction logs and snapshots forever. Disk consumption is silent and cliff-edge. By the time &lt;code>ruok&lt;/code> fails, the process is already gone.&lt;/p></description></item><item><title>ZooKeeper unexpected leader election: finding why the leader dropped</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-unexpected-leader-election/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-unexpected-leader-election/</guid><description>&lt;h1 id="zookeeper-unexpected-leader-election-finding-why-the-leader-dropped">ZooKeeper unexpected leader election: finding why the leader dropped&lt;/h1>
&lt;p>An unexpected ZooKeeper leader election is an availability event. While the ensemble is in LOOKING state, no writes are processed. Systems that depend on ZK for coordination queue or fail their mutations, and &lt;code>zk_sum_leader_unavailable_time&lt;/code> climbs. Treat every unplanned election like a database failover: the cluster recovered, but you still need the root cause.&lt;/p>
&lt;p>The cause is on the old leader or on the path to it. Followers call an election when they have not heard from the leader within &lt;code>syncLimit * tickTime&lt;/code> (default 5 * 2000ms = 10 seconds). The question is always: what stopped the old leader from sending heartbeats, or what stopped a quorum of followers from receiving them.&lt;/p></description></item><item><title>ZooKeeper unrecoverable error: when a node's integrity is compromised</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-unrecoverable-error/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-unrecoverable-error/</guid><description>&lt;h1 id="zookeeper-unrecoverable-error-when-a-nodes-integrity-is-compromised">ZooKeeper unrecoverable error: when a node&amp;rsquo;s integrity is compromised&lt;/h1>
&lt;p>You got paged because &lt;code>zk_unrecoverable_error_count&lt;/code> incremented. This is one of the few &lt;code>mntr&lt;/code> counters you never want to see move. It tracks errors ZooKeeper cannot recover from internally: data corruption, invariant violations, or resource exhaustion that puts the node into a state it cannot safely keep serving from.&lt;/p>
&lt;p>ZooKeeper is designed to fail fast. When it hits an unrecoverable condition it does not limp along. The critical thread logs a severe error, notifies the supervision listener, and the process exits. By the time the counter increments, the JVM is usually already gone or about to be, and the question is no longer &amp;ldquo;is this node healthy&amp;rdquo; but &amp;ldquo;do I trust its on-disk state at all&amp;rdquo;.&lt;/p></description></item><item><title>ZooKeeper watch storm: thousands of notifications when one hot znode changes</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-watch-count-storm/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-watch-count-storm/</guid><description>&lt;h1 id="zookeeper-watch-storm-thousands-of-notifications-when-one-hot-znode-changes">ZooKeeper watch storm: thousands of notifications when one hot znode changes&lt;/h1>
&lt;p>A single znode changes. Seconds later, &lt;code>zk_packets_sent&lt;/code> spikes to many times its normal rate, CPU on the ZooKeeper process surges, and &lt;code>zk_outstanding_requests&lt;/code> begins climbing. Clients report latency spikes, connection timeouts, or session expirations. If many clients watch the same znode, you are looking at a watch storm.&lt;/p>
&lt;p>The mechanism: ZooKeeper maintains a watch table mapping znode paths to registered watchers. When a watched znode changes, the server queues a notification for every client that registered a watch on that path. For a path with 10,000 watchers, a single &lt;code>setData&lt;/code> call produces 10,000 notification packets. Notification serialization and queuing happen inside the request processing pipeline, competing with all other request handling.&lt;/p></description></item><item><title>ZooKeeper with no authentication: the open-by-default coordination store</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-no-authentication-open-access/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-no-authentication-open-access/</guid><description>&lt;h1 id="zookeeper-with-no-authentication-the-open-by-default-coordination-store">ZooKeeper with no authentication: the open-by-default coordination store&lt;/h1>
&lt;p>ZooKeeper ships with no authentication by default. Any TCP client that can reach port 2181 can open a session, read any znode, and write any znode whose ACL has not been explicitly restricted. The default ACL on znodes created without an explicit ACL is &lt;code>OPEN_ACL_UNSAFE&lt;/code>: &lt;code>world:anyone&lt;/code> with full &lt;code>cdrwa&lt;/code> (create, read, write, delete, admin) permissions.&lt;/p>
&lt;p>This matters because ZooKeeper is the coordination store for systems that treat its contents as authoritative: Kafka broker registrations and controller elections (pre-KRaft), HBase region assignment and master election, HDFS NameNode HA fencing state. An unauthenticated writer in those subtrees can silently corrupt cluster state, force leader changes, or trigger cascading failovers, and the writes succeed because the ACL permits them. There is no second layer that catches them.&lt;/p></description></item><item><title>ZooKeeper write latency high: read zk_updatelatency, not just avg_latency</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-write-latency-high/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-write-latency-high/</guid><description>&lt;h1 id="zookeeper-write-latency-high-read-zk_updatelatency-not-just-avg_latency">ZooKeeper write latency high: read zk_updatelatency, not just avg_latency&lt;/h1>
&lt;p>The dashboard says ZooKeeper is fine. &lt;code>zk_avg_latency&lt;/code> is 2ms. Clients are timing out anyway: distributed locks expiring mid-acquisition, Kafka controllers flapping, HBase regions bouncing. The signal you are missing is &lt;code>zk_updatelatency&lt;/code>, the write-specific latency family that 3.6+ exposes separately from the misleading aggregate.&lt;/p>
&lt;p>The trap is structural. &lt;code>zk_avg_latency&lt;/code>, &lt;code>zk_min_latency&lt;/code>, and &lt;code>zk_max_latency&lt;/code> from &lt;code>mntr&lt;/code> combine reads and writes into one cumulative statistic. Reads are local in-memory lookups, typically sub-millisecond. Writes require a leader round-trip, a ZAB proposal, a quorum ACK, a commit, and an fsync. When read volume dominates, a healthy average masks pathological write latency. These are also server-cumulative statistics since the last &lt;code>srst&lt;/code> reset, not sliding windows: a single fsync stall from three hours ago still inflates &lt;code>zk_max_latency&lt;/code>.&lt;/p></description></item><item><title>ZooKeeper znode count growing unbounded: the silent heap killer</title><link>https://www.netdata.cloud/guides/zookeeper/zookeeper-znode-count-growing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.netdata.cloud/guides/zookeeper/zookeeper-znode-count-growing/</guid><description>&lt;h1 id="zookeeper-znode-count-growing-unbounded-the-silent-heap-killer">ZooKeeper znode count growing unbounded: the silent heap killer&lt;/h1>
&lt;p>The symptom is familiar: a ZooKeeper ensemble that ran cleanly for months suddenly enters a GC death spiral. Heap climbs, full GC pauses stretch from milliseconds to seconds, sessions expire, and the JVM OOMs. The process restarts, the data tree reloads from snapshot, and the cycle repeats. All members OOM at roughly the same time because they carry the same in-memory data tree.&lt;/p></description></item></channel></rss>