kovidgoyal/kitty · warning
poll() on talk fds failed
Error message
poll() on talk fds failed
What it means
perror emitted when poll() over the 'talk' file descriptors (kitty's internal peer/remote-control IPC sockets) returns a negative value that is not EAGAIN or EINTR. This means the multiplexed IPC event loop in child-monitor.c could not wait on its sockets, usually due to a bad/stale fd or EBADF/EFAULT after a peer died. kitty logs it and continues; it indicates IPC plumbing trouble rather than a terminal failure.
Source
Thrown at kitty/child-monitor.c:2271
for (size_t k = 0; k < talk_data.num_peers; k++) {
Peer *p = talk_data.peers + k;
if (p->fd_array_idx) {
if (fds[p->fd_array_idx].revents & POLLIN) read_from_peer(self, p);
if (fds[p->fd_array_idx].revents & POLLOUT) write_to_peer(p);
if (fds[p->fd_array_idx].revents & POLLHUP) {
// try to read and write nonetheless these functions will set the failed flags.
if (!p->read.finished) read_from_peer(self, p);
if (p->write.used) write_to_peer(p);
}
if (fds[p->fd_array_idx].revents & POLLNVAL) {
p->read.finished = true;
p->write.failed = true;
p->write.used = 0;
}
}
}
} else if (ret < 0) {
if (errno != EAGAIN && errno != EINTR) perror("poll() on talk fds failed");
}
}
end:
free_loop_data(&talk_data.loop_data);
for (size_t i = 0; i < talk_data.num_peers; i++) free_peer(talk_data.peers + i);
free(talk_data.peers);
return 0;
}
static void
send_response_to_peer(id_type peer_id, const char *msg, size_t msg_sz, bool is_async_response) {
bool wakeup = false;
talk_mutex(lock);
for (size_t i = 0; i < talk_data.num_peers; i++) {
Peer *peer = talk_data.peers + i;
if (peer->id == peer_id) {
peer->waiting_for_async_response = is_async_response;
if (peer->num_of_unresponded_messages_sent_to_main_thread) peer->num_of_unresponded_messages_sent_to_main_thread--;View on GitHub (pinned to 6d5d0c4406)
Solutions
- Check dmesg/system logs for fd exhaustion; raise ulimit -n if the process is near its limit.
- Update kitty — stale-peer fd handling in the talk loop has been fixed in newer releases.
- Reproduce with KITTY_DEBUG / --debug-ipc if available and report the errno value printed after the message.
- If tied to a kitten, restart the kitten rather than the whole kitty session; the main loop recovers.
Defensive patterns
Strategy: fallback
Prevention
- Keep peer kittens and the kitty main binary on the same version.
- Avoid spawning hundreds of concurrent peer kittens that die abruptly.
- Monitor fd usage (ls /proc/$(pidof kitty)/fd | wc -l) in automation.
When it happens
Trigger: poll() returning -1 with errno such as EBADF (a closed talk fd still in the poll set), EFAULT (fds array out of reach), or ENOMEM, while running kitty with remote control (--listen-on), single-instance sockets, or peer kittens talking to the main process.
Common situations: A peer kitten or socket client crashes mid-connection leaving a stale fd; fd exhaustion on systems with many kittens/windows; bugs in older kitty versions where dead peer fds were not removed from the poll set.
Related errors
- Incorrect password
- Incorrect request id: {rq_id!r} expecting the KITTY_PID-KITT
- failed to export interface: %s at object path: %s with error
- This must be run as kitten ask
- This should be run as kitten broadcast
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/afa2e9f92bff11c5.
Report an issue: GitHub.