t8y2/dbx · error

read ZooKeeper connect response: %w

Error message

read ZooKeeper connect response: %w

What it means

After writing the connect request, newProtocolZooKeeperClient reads the server's connect response frame via readFrame. If reading fails (EOF, connection closed, timeout, short frame), the error is wrapped as 'read ZooKeeper connect response'. The server was reached but never delivered a complete handshake reply.

Source

Thrown at agents/drivers/argo-go/zookeeper_protocol.go:160

	if connection == nil {
		return nil, errors.New("ZooKeeper connection is nil")
	}
	if timeout <= 0 {
		timeout = defaultConnectTimeout
	}
	client := &protocolZooKeeperClient{connection: connection, timeout: timeout}
	request := &zooKeeperEncoder{}
	request.int32(zooKeeperProtocolVersion)
	request.int64(0)
	request.int32(zooKeeperTimeoutMillis(timeout))
	request.int64(0)
	request.bytes(make([]byte, 16))
	if err := client.writeFrame(request.data()); err != nil {
		return nil, fmt.Errorf("send ZooKeeper connect request: %w", err)
	}
	response, err := client.readFrame()
	if err != nil {
		return nil, fmt.Errorf("read ZooKeeper connect response: %w", err)
	}
	decoder := newZooKeeperDecoder(response)
	if _, err := decoder.int32(); err != nil {
		return nil, fmt.Errorf("decode ZooKeeper protocol version: %w", err)
	}
	if _, err := decoder.int32(); err != nil {
		return nil, fmt.Errorf("decode ZooKeeper session timeout: %w", err)
	}
	sessionID, err := decoder.int64()
	if err != nil {
		return nil, fmt.Errorf("decode ZooKeeper session ID: %w", err)
	}
	if _, err := decoder.bytes(); err != nil {
		return nil, fmt.Errorf("decode ZooKeeper session password: %w", err)
	}
	if sessionID == 0 {
		return nil, zk.ErrSessionExpired
	}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Check server-side limits (maxClientCnxns, connection queue) in zoo.cfg — servers drop clients at the limit
  2. Verify the port is really ZooKeeper and not another service that closes on unknown bytes
  3. Increase the connect timeout so slow ensembles can respond within the read deadline
  4. Inspect server logs for connection drops at the same timestamp and retry with failover
Defensive patterns

Strategy: retry

Validate before calling

if err := tcpReachable(address, 5*time.Second); err != nil { return fmt.Errorf("zk %s unreachable: %w", address, err) }

Try / catch

client, err := newProtocolZooKeeperClient(conn, timeout)
if err != nil {
    if strings.Contains(err.Error(), "read ZooKeeper connect response") {
        // server reached but no reply: retry next member / increase deadline
        return dialNextMember(ensemble)
    }
    return err
}

Prevention

When it happens

Trigger: Calling newProtocolZooKeeperClient (via connectKerberosZooKeeper or the protocol tests) where readFrame errors: peer closed the connection after receiving the connect request, read deadline expired before a response, or the server returned a truncated/invalid frame.

Common situations: ZooKeeper server rejecting the client and closing mid-handshake (maxClientCnxns exceeded, wrong port hitting a non-ZK service); overly aggressive timeout killing a slow session establishment; proxy intercepting the protocol stream.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/1d66ecb082370db9. Report an issue: GitHub.