In macOS, when a queued client disconnects before being accepted, ListenConnections's accept path throws:
mp/proxy.cpp:48: error: Uncaught exception in daemonized task.; exception = kj/async-io-unix.c++:1365: failed: setsocketopt(IPPROTO_TCP, TCP_NODELAY): Invalid argument
This issue was first seen while working on adding coverage for ListenConnections in #310. While reviewing bitcoin/bitcoin#35037, I came across it again while experimenting with socat. It's trivial to hit because of the new -ipcbind settings introduced there.
To reproduce it, here are the steps (macOS):
The bitcoin/bitcoin#35037 branch is needed since it has a
max-connectionscli setting available, so pull the changes and compilebitcoin-node.Start
bitcoin-nodein regtest and cap the connection limit at 1./build/bin/bitcoin-node -regtest -ipcbind=unix:/tmp/a.sock,max-connections=1In another terminal (let's call it terminal A), connect to the listening address using socat.
socat - UNIX-CONNECT:/tmp/a.sockThe node should log the accepted connection:
2026-07-23T18:52:00Z ipc: {bitcoin-node-90447/b-capnp-loop-13449344} IPC server: socket connected.Because the connection slots are limited to only one, a single connection is enough to saturate it and start queuing new ones.
Open another terminal (Terminal B), try to connect to the listener again using the command from step 3. Since the listener is already saturated, the connection shouldn't be accepted, so no new "socket connected" log line should appear.
At this point, the second connection is queued, so close it in Terminal B.
Next, close the accepted connection in Terminal A so the listener attempts to accept the already-dead socket that is next in the queue, triggering the bug.
2026-07-23T19:21:31Z ipc: {bitcoin-node-1724/b-capnp-loop-13498216} IPC server: socket disconnected. mp/proxy.cpp:48: error: Uncaught exception in daemonized task.; exception = kj/async-io-unix.c++:1365: failed: setsocketopt(IPPROTO_TCP, TCP_NODELAY): Invalid argument stack: 105b5b327 105b5abbb 1047447b7 1047464bb 1047468e3 2026-07-23T19:21:31Z [error] ipc: {bitcoin-node-1724/b-capnp-loop-13498216} Uncaught exception in daemonized task.Now the listener has stopped accepting connections
$ socat - UNIX-CONNECT:/tmp/a.sock 2026/07/23 16:26:36 socat[3651] E connect(, LEN=13 AF=1 "/tmp/a.sock", 13): Connection refusedThis is a Cap'n Proto bug, @ViniciusCestarii found the root cause (see #310#pullrequestreview-4723481031): After
accept(), kj always callssetsockopt(TCP_NODELAY)on the connection socket. For Unix sockets, kj handles the usual "not supported" error codes. On macOS,EINVALis returned when the client has already disconnected, but kj only tolerates that code when built for FreeBSD. The unexpected error then goes uncaught in the accept loop (escapesmp::ListenConnections), causing the listener to stop accepting new connections.
It's fixed on capnproto's v2 branch (capnproto/capnproto@7df5bd078), but no release includes it. I proposed another solution at the libmultiprocess layer, but it unconditionally (and dangerously) continued the accept loop, ignoring errors that may deserve attention.
Until it's released (or backported), a temporary workaround may be to add a patch to Bitcoin Core's depends, as suggested by @ryanofsky in #310#pullrequestreview-4724053865. I've already opened a PR to Bitcoin Core: bitcoin/bitcoin#35796.