t8y2/dbx · error

ZooKeeper request frame is %d bytes, maximum is %d

Error message

ZooKeeper request frame is %d bytes, maximum is %d

What it means

The client refuses to send a ZooKeeper request whose serialized payload exceeds zooKeeperMaxFrameSize. The ZooKeeper wire protocol prefixes each request with a 4-byte big-endian length, so oversized payloads are rejected before writing to protect both the client and the server from invalid or hostile frames. This is a client-side pre-flight check in writeFrame, raised before any bytes hit the socket.

Source

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

	if xid != client.xid {
		return nil, fmt.Errorf("ZooKeeper response XID %d does not match request XID %d", xid, client.xid)
	}
	if _, err := decoder.int64(); err != nil {
		return nil, err
	}
	code, err := decoder.int32()
	if err != nil {
		return nil, err
	}
	if err := zooKeeperError(code); err != nil {
		return nil, err
	}
	return decoder.remaining(), nil
}

func (client *protocolZooKeeperClient) writeFrame(payload []byte) error {
	if len(payload) > zooKeeperMaxFrameSize {
		return fmt.Errorf("ZooKeeper request frame is %d bytes, maximum is %d", len(payload), zooKeeperMaxFrameSize)
	}
	if err := client.connection.SetWriteDeadline(time.Now().Add(client.timeout)); err != nil {
		return err
	}
	header := make([]byte, 4)
	binary.BigEndian.PutUint32(header, uint32(len(payload)))
	if err := writeAll(client.connection, header); err != nil {
		return err
	}
	return writeAll(client.connection, payload)
}

func (client *protocolZooKeeperClient) readFrame() ([]byte, error) {
	if err := client.connection.SetReadDeadline(time.Now().Add(client.timeout)); err != nil {
		return nil, err
	}
	header := make([]byte, 4)
	if _, err := io.ReadFull(client.connection, header); err != nil {

View on GitHub (pinned to c0390bff16)

Solutions

  1. Shrink the payload: split large node data into chunked child znodes (e.g. chunk-N under a parent) and reassemble on read.
  2. Move large payloads to object storage (S3/GCS) and store only a reference/URL in the znode.
  3. Check what you are encoding — log len(payload) before the call and confirm the data size is what you expect (accidental double-encoding or embedding of a whole config file is common).
  4. If you control deployment and genuinely need larger frames, raise zooKeeperMaxFrameSize in this driver together with the server's jute.maxbuffer; otherwise the server will reject the frame anyway.

Example fix

// before
err := zkClient.Set(path, bigBlob, version) // bigBlob is 2 MB

// after
const chunkSize = 512 * 1024
for i, chunk := range chunks(bigBlob, chunkSize) {
    if err := zkClient.Create(fmt.Sprintf("%s/chunk-%d", path, i), chunk, 0, zk.WorldACL(zk.PermAll)); err != nil {
        return err
    }
}
Defensive patterns

Strategy: validation

Validate before calling

const zooKeeperMaxFrameSize = 1 << 20 // match the driver's cap
if len(payload) > zooKeeperMaxFrameSize {
    return fmt.Errorf("payload too large for a single znode: %d bytes", len(payload))
}
// otherwise proceed with the Set/Create call

Prevention

When it happens

Trigger: Any request whose encoded payload (xid + type + path + data/acl/watch fields) exceeds zooKeeperMaxFrameSize: calling Create/Set/Data operations with very large node data, or setting a node with an ACL list so long the encoded frame exceeds the cap.

Common situations: Storing large blobs (images, serialized documents, big JSON) in znodes instead of object storage; a bug in the encoder producing a garbage-length buffer; writing more than the ~1MB default jute.maxbuffer the server itself enforces, where the client cap trips first.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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