t8y2/dbx · error
invalid ZooKeeper buffer length %d
Error message
invalid ZooKeeper buffer length %d
What it means
When decoding a length-prefixed byte buffer from a ZooKeeper response, a negative length other than the legal -1 (NULL) sentinel means the stream is corrupt or misaligned. The decoder rejects the value in decoder.bytes rather than attempting a take() with a negative size, which would otherwise fail opaquely as io.ErrUnexpectedEOF.
Source
Thrown at agents/drivers/argo-go/zookeeper_protocol.go:491
func (decoder *zooKeeperDecoder) int64() (int64, error) {
value, err := decoder.take(8)
if err != nil {
return 0, err
}
return int64(binary.BigEndian.Uint64(value)), nil
}
func (decoder *zooKeeperDecoder) bytes() ([]byte, error) {
length, err := decoder.int32()
if err != nil {
return nil, err
}
if length == -1 {
return nil, nil
}
if length < -1 {
return nil, fmt.Errorf("invalid ZooKeeper buffer length %d", length)
}
value, err := decoder.take(int(length))
if err != nil {
return nil, err
}
return append([]byte(nil), value...), nil
}
func (decoder *zooKeeperDecoder) string() (string, error) {
value, err := decoder.bytes()
return string(value), err
}
func (decoder *zooKeeperDecoder) strings() ([]string, error) {
length, err := decoder.int32()
if err != nil {
return nil, err
}View on GitHub (pinned to c0390bff16)
Solutions
- Discard the client connection and re-dial — a corrupt length means the byte stream is misaligned and cannot be recovered on the same socket.
- Verify the endpoint is a real ZooKeeper server on port 2181 (or your configured port) and that TLS settings match the server.
- Check for concurrent use of one client/connection from multiple goroutines — interleaved reads corrupt the framing; serialize access or use one client per goroutine.
- Capture the raw bytes (or enable protocol-level logging) around the failure to identify where the stream diverged.
Example fix
// before
resp, err := client.request(payload) // client reused across goroutines
// after
mu.Lock()
defer mu.Unlock()
resp, err := client.request(payload) // serialize access to the shared connection
if err != nil {
client.Close() // framing is unrecoverable; force re-dial
return err
} Defensive patterns
Strategy: retry
Validate before calling
// verify the endpoint speaks ZooKeeper before parsing responses
conn, err := net.DialTimeout("tcp", addr, 3*time.Second)
if err != nil {
return err
}
conn.SetDeadline(time.Now().Add(3 * time.Second))
// a four-byte probe read of a real ZooKeeper reply will never start with an
// implausible length; garbage on connect means wrong service
conn.Close() Type guard
func isFrameCorruption(err error) bool {
if err == nil {
return false
}
return strings.Contains(err.Error(), "invalid ZooKeeper buffer length") ||
errors.Is(err, io.ErrUnexpectedEOF)
} Try / catch
value, err := client.Get(path)
if isFrameCorruption(err) {
client.Close()
client = redial() // stream is misaligned; a fresh connection is required
value, err = client.Get(path)
}
return value, err Prevention
- Re-dial on any decoder error; framing cannot self-heal mid-stream.
- Serialize all reads/writes on a shared client with a mutex, or use one client per goroutine.
- Confirm TLS/plaintext parity with the server before connecting.
- Watch for proxies or port-forwards altering traffic on the ZooKeeper port.
When it happens
Trigger: Parsing any response containing a buffer field (node data, SASL payload, stat-associated fields) where the length int32 is < -1: reading from a desynchronized stream, a response produced by a non-ZooKeeper peer, or frame bytes corrupted in transit.
Common situations: Reusing a connection after a previous read timed out mid-frame (offset shifted into the payload); a MITM proxy or port-forward that alters traffic; connecting to a service speaking a different protocol on the ZooKeeper port; driver/server protocol-version mismatch producing shifted fields.
Related errors
- ZooKeeper response frame is %d bytes, maximum is %d
- invalid ZooKeeper string vector length %d
- ZooKeeper sent an unexpected token after GSSAPI completion
- ZooKeeper connection is nil
- ZooKeeper sent an unexpected token after GSSAPI completion
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/ccaf2000e8d34345.
Report an issue: GitHub.