What happened?
In salt/transport/zeromq.py, both AsyncReqMessageClient._send_recv and RequestClient._send_recv treat a single hard-coded 300ms socket.poll(..., zmq.POLLOUT) miss as an immediate request timeout:
if not await socket.poll(300, zmq.POLLOUT):
if not future.done():
future.set_exception(
SaltReqTimeoutError("Socket not ready for sending")
)
if not self._closing:
await self._reconnect()
break
This produces the familiar minion log line:
Request timed out while waiting for a response. reconnecting.
even when the caller passed a much larger timeout to send() (e.g. via return_retry_timer / request_channel_timeout). That timeout is applied separately with io_loop.call_later(timeout, self._timeout_message, future), which is the intended request deadline.
Expected behavior
The 300ms value should only be a readiness poll slice (same pattern as the POLLIN loop that follows). _send_recv should keep polling for POLLOUT until either:
- the socket becomes write-ready and the message is sent, or
- the future is already done because
_timeout_message fired at the configured request timeout.
It should not call future.set_exception(SaltReqTimeoutError(...)) on a POLLOUT miss before that configured deadline.
Contrast with POLLIN path (already correct)
while True:
if future.done():
break
ready = await socket.poll(300, zmq.POLLIN)
...
Suggested fix
Mirror POLLIN:
sent = False
while not future.done():
if await socket.poll(300, zmq.POLLOUT):
await socket.send(message)
sent = True
break
if not sent:
continue # configured timeout already completed the future
Impact
Under master backpressure / slow REQ socket write readiness (e.g. overloaded Salt master), job results can complete on the minion but fail to publish because the return path aborts after 300ms despite return_retry_timer / request_channel_timeout being configured much higher. Raising those options has no effect on this POLLOUT path because the 300ms constant is not read from opts.
Notes
- Observed on Salt
3008.0rc4 (not in the Major version dropdown yet); code pattern is present in current salt/transport/zeromq.py for both request client classes.
- 300ms is not configurable via any Salt opt (
zmq_backlog / pub_hwm / etc. do not apply).
Type of salt install
Official rpm (appliance-packaged Salt)
Major version
- 3007.x (pattern also present on 3008.0rc4)
What supported OS are you seeing the problem on?
- photon-5 (vCenter / VCF appliance minion)
salt --versions-report output
Salt: 3008.0rc4
Python: 3.14.5
(Truncated; full report available on request.)
What happened?
In
salt/transport/zeromq.py, bothAsyncReqMessageClient._send_recvandRequestClient._send_recvtreat a single hard-coded 300mssocket.poll(..., zmq.POLLOUT)miss as an immediate request timeout:This produces the familiar minion log line:
even when the caller passed a much larger timeout to
send()(e.g. viareturn_retry_timer/request_channel_timeout). That timeout is applied separately withio_loop.call_later(timeout, self._timeout_message, future), which is the intended request deadline.Expected behavior
The 300ms value should only be a readiness poll slice (same pattern as the POLLIN loop that follows).
_send_recvshould keep polling for POLLOUT until either:_timeout_messagefired at the configured request timeout.It should not call
future.set_exception(SaltReqTimeoutError(...))on a POLLOUT miss before that configured deadline.Contrast with POLLIN path (already correct)
Suggested fix
Mirror POLLIN:
Impact
Under master backpressure / slow REQ socket write readiness (e.g. overloaded Salt master), job results can complete on the minion but fail to publish because the return path aborts after 300ms despite
return_retry_timer/request_channel_timeoutbeing configured much higher. Raising those options has no effect on this POLLOUT path because the 300ms constant is not read from opts.Notes
3008.0rc4(not in the Major version dropdown yet); code pattern is present in currentsalt/transport/zeromq.pyfor both request client classes.zmq_backlog/pub_hwm/ etc. do not apply).Type of salt install
Official rpm (appliance-packaged Salt)
Major version
What supported OS are you seeing the problem on?
salt --versions-report output
(Truncated; full report available on request.)