locustio/locust · error · RPCSendError

ZMQ sent failure

Error message

ZMQ sent failure

What it means

RPCSendError raised when the ZMQ send on a ROUTER/DEALER socket fails. The library wraps the underlying zmq.error.ZMQError so distributed-runner code only has to handle locust's RPC exception types. The send uses zmq.NOBLOCK, so it fails immediately instead of blocking (e.g. when the socket cannot accept the message).

Source

Thrown at locust/rpc/zmqrpc.py:29

from .protocol import Message


class BaseSocket:
    def __init__(self, sock_type, ipv4_only):
        context = zmq.Context()
        self.socket = context.socket(sock_type)

        self.socket.setsockopt(zmq.TCP_KEEPALIVE, 1)
        self.socket.setsockopt(zmq.TCP_KEEPALIVE_IDLE, 30)
        if has_dualstack_ipv6() and not ipv4_only:
            self.socket.setsockopt(zmq.IPV6, 1)

    @retry()
    def send(self, msg):
        try:
            self.socket.send(msg.serialize(), zmq.NOBLOCK)
        except zmqerr.ZMQError as e:
            raise RPCSendError("ZMQ sent failure") from e

    @retry()
    def send_to_client(self, msg):
        try:
            self.socket.send_multipart([msg.node_id.encode(), msg.serialize()])
        except zmqerr.ZMQError as e:
            raise RPCSendError("ZMQ sent failure") from e

    def recv(self):
        try:
            data = self.socket.recv()
            msg = Message.unserialize(data)
        except msgerr.ExtraData as e:
            raise RPCReceiveError("ZMQ interrupted message") from e
        except zmqerr.ZMQError as e:
            raise RPCError("ZMQ network broken") from e
        return msg

View on GitHub (pinned to f391a716e1)

Solutions

  1. Check that the remote master/worker process is running and the host/port are correct
  2. Retry the message send; transient EAGAIN errors usually clear once the peer drains its queue
  3. Verify the socket has not been closed (e.g. after Environment quit) before sending
  4. Upgrade/verify pyzmq and libzmq versions if errors persist on valid sockets

Example fix

// before
runner.environment.events...  # sending after runner quit raises RPCSendError
runner.send_message(Message('client_stopped', None, None))
// after
if runner.state != STATE_STOPPED:
    runner.send_message(Message('client_stopped', None, None))
Defensive patterns

Strategy: retry

Validate before calling

if runner.state == STATE_STOPPED or runner.state == STATE_STOPPING:
    raise RuntimeError('Runner stopped; cannot send messages')

Try / catch

try:
    client.send(msg)
except RPCSendError:
    logger.warning('ZMQ send failed; peer may be down')
    # retry with backoff or mark peer unreachable

Prevention

When it happens

Trigger: Calling BaseSocket.send() (used by Runner.send_message / send_to_client paths) when the underlying ZMQ socket raises ZMQError on a non-blocking send — typically an unbound/closed socket, EAGAIN (HWM reached, NOBLOCK), or an unreachable peer.

Common situations: Master/worker test where the counterpart process crashed or the socket was closed; network partition between master and workers; sending on a socket that was never connected (worker not started or wrong host/port).

Related errors


AI-assisted analysis of locustio/locust@f391a716e1 (2026-08-29). Data as JSON: /api/errors/2ecfb87b480e9b2a. Report an issue: GitHub.