nodejs/node · error
select fail: %d
Error message
select fail: %d
What it means
Printed by the adig tool's event loop at adig.c:900 when the select() system call returns a negative value (count < 0) and the error is neither EAGAIN nor EINTR. The message includes the numeric errno value. On Windows it uses WSAGetLastError(), on other platforms errno. The tool returns 1 (failure), terminating the DNS query loop. select() monitors the file descriptors that c-ares is watching for DNS response traffic.
Source
Thrown at deps/cares/src/tools/adig.c:900
memset(&tv, 0, sizeof(tv));
nfds = ares_fds(channel, &read_fds, &write_fds);
if (nfds == 0) {
break;
}
tvp = ares_timeout(channel, NULL, &tv);
if (tvp == NULL) {
break;
}
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
if (count < 0) {
#ifdef USE_WINSOCK
int err = WSAGetLastError();
#else
int err = errno;
#endif
if (err != EAGAIN && err != EINTR) {
fprintf(stderr, "select fail: %d", err);
return 1;
}
}
ares_process(channel, &read_fds, &write_fds);
}
return 0;
}
typedef enum {
OPT_TYPE_BOOL,
OPT_TYPE_STRING,
OPT_TYPE_SIZE_T,
OPT_TYPE_U16,
OPT_TYPE_FUNC
} opt_type_t;
/* Callback called with OPT_TYPE_FUNC when processing options.
* \param[in] prefix prefix character for optionView on GitHub (pinned to 1b2de5e052)
Solutions
- Check the numeric errno printed: EBADF (9) means an invalid FD — investigate whether c-ares sockets were prematurely closed.
- Increase the file descriptor limit with 'ulimit -n' if nfds exceeds the soft limit.
- If running in a container, verify the seccomp profile and namespace settings allow select() and socket operations.
- Ensure only one thread is using the c-ares channel and that ares_destroy is not called concurrently with the event loop.
Example fix
// before: event loop fails on select error // adig example.com // prints 'select fail: 9' (EBADF) // after: check fd limits and channel lifecycle ulimit -n 65536 // raise fd limit // ensure ares_destroy(channel) is called only after event_loop returns
Defensive patterns
Strategy: validation
Validate before calling
// Before entering the event loop, check fd limits
#include <sys/resource.h>
struct rlimit rl;
if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
if (rl.rlim_cur < 1024) {
rl.rlim_cur = rl.rlim_max;
setrlimit(RLIMIT_NOFILE, &rl);
}
}
// Ensure the c-ares channel is valid and not destroyed concurrently Try / catch
// In the event loop, handle EAGAIN/EINTR gracefully (adig already does this)
// For other errors, log errno and break rather than crash
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
if (count < 0 && errno != EAGAIN && errno != EINTR) {
// log errno, clean up channel, exit gracefully
break;
} Prevention
- Raise file descriptor limits (ulimit -n) before running DNS tools in production.
- Ensure ares_destroy() is not called concurrently with the event loop.
- Verify container seccomp profiles allow select() and socket operations.
When it happens
Trigger: The select() call in adig's event_loop (line 892) fails with an unrecoverable error. This happens when the file descriptor set passed to select() contains an invalid FD (EBADF), the nfds argument exceeds the process's FD limit, or the system call is interrupted by a signal that is not EINTR/EAGAIN. On Windows, a WinSock error such as WSAENOTSOCK or WSAEINVAL triggers it.
Common situations: Running adig in a container or sandbox with restricted file descriptor limits. A c-ares channel has internal sockets that were closed out from under it (double-close, use-after-close). A misconfigured seccomp filter blocks select(). Running on a platform where select() has platform-specific quirks (very large FD numbers).
Related errors
- ares_library_init: %s
- ** ERROR: %s
- ares_init_options: %s
- ares_set_servers_ports_csv: %s: %s
- Failed to create query for %s: %s
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/68b9d858d1accb71.
Report an issue: GitHub.