curl/curl ยท error
curl_multi_waitfds() failed, code %d.
Error message
curl_multi_waitfds() failed, code %d.
What it means
Printed in the curl_multi_waitfds example on the first (probe) call curl_multi_waitfds(multi, NULL, 0, &fd_count), which is the documented way to discover how many descriptors the multi handle uses before allocating storage. A non-zero CURLMcode means even this size query failed. The %d is the CURLMcode. curl_multi_waitfds was added in libcurl 8.8.0.
Source
Thrown at docs/libcurl/curl_multi_waitfds.md:79
#include <stdlib.h>
int main(void)
{
CURLMcode mresult;
struct curl_waitfd *ufds;
CURLM *multi = curl_multi_init();
do {
/* call curl_multi_perform() */
/* get the count of file descriptors from the transfers */
unsigned int fd_count = 0;
mresult = curl_multi_waitfds(multi, NULL, 0, &fd_count);
if(mresult != CURLM_OK) {
fprintf(stderr, "curl_multi_waitfds() failed, code %d.\n", mresult);
break;
}
if(!fd_count)
continue; /* no descriptors yet */
/* allocate storage for our descriptors */
ufds = malloc(fd_count * sizeof(struct curl_waitfd));
/* get wait descriptors from the transfers and put them into array. */
mresult = curl_multi_waitfds(multi, ufds, fd_count, &fd_count);
if(mresult != CURLM_OK) {
fprintf(stderr, "curl_multi_waitfds() failed, code %d.\n", mresult);
free(ufds);
break;
}
View on GitHub (pinned to 527573490e)
Solutions
- Check libcurl version at build/run time (need >= 8.8.0) since curl_multi_waitfds did not exist before then.
- Verify curl_multi_init() returned a valid, non-NULL CURLM* and that it has not been cleaned up.
- Ensure the call is not made from inside a libcurl callback (CURLM_RECURSIVE_API_CALL).
- On CURLM_OUT_OF_MEMORY, investigate overall process memory; on CURLM_INTERNAL_ERROR, upgrade libcurl and report the bug.
Example fix
// before
mresult = curl_multi_waitfds(multi, NULL, 0, &fd_count);
if(mresult != CURLM_OK) {
fprintf(stderr, "curl_multi_waitfds() failed, code %d.\n", mresult);
break;
}
// after - guard handle and version, report symbolically
if(!multi) { fprintf(stderr, "multi handle is NULL\n"); break; }
mresult = curl_multi_waitfds(multi, NULL, 0, &fd_count);
if(mresult != CURLM_OK) {
fprintf(stderr, "curl_multi_waitfds() probe failed: %s (%d)\n",
curl_multi_strerror(mresult), mresult);
break;
} Defensive patterns
Strategy: validation
Validate before calling
// First call: query the descriptor count with a NULL buffer.
if (multi == NULL) { return -1; }
unsigned int fd_count = 0;
/* size == 0 is the documented way to ask for the count. */
CURLMcode q = curl_multi_waitfds(multi, NULL, 0, &fd_count);
if (q != CURLM_OK || fd_count == 0) { /* nothing to wait on yet */ } Type guard
// Validate the count probe before allocating.
static bool fd_count_usable(unsigned int n) {
return n > 0 && n < (1024u * 1024u); /* sanity ceiling against runaway */
} Try / catch
mresult = curl_multi_waitfds(multi, NULL, 0, &fd_count);
if (mresult != CURLM_OK) {
fprintf(stderr, "curl_multi_waitfds() failed, code %d.\n", (int)mresult);
break;
} Prevention
- Call curl_multi_waitfds once with size 0 to learn fd_count before allocating any buffer.
- Guard the multi handle for NULL; CURLM_BAD_HANDLE is returned otherwise.
- Treat fd_count == 0 as 'no descriptors yet', not an error: continue the loop.
- Size your allocation to at least fd_count; passing a smaller size triggers CURLM_OUT_OF_MEMORY.
When it happens
Trigger: curl_multi_waitfds(multi, NULL, 0, &fd_count) returns CURLM_BAD_HANDLE (1) when multi is NULL, freed, or not a CURLM handle; CURLM_OUT_OF_MEMORY (3); or CURLM_INTERNAL_ERROR (4). Because size=0 is explicitly the supported probe path, an OUT_OF_MEMORY here indicates genuine memory pressure rather than a too-small buffer.
Common situations: Calling curl_multi_waitfds on a libcurl older than 8.8.0 where the symbol is absent (link-time or runtime symbol error, not a CURLMcode but worth checking); passing a handle before curl_multi_init or after curl_multi_cleanup; running under severe memory pressure; calling from within a callback (CURLM_RECURSIVE_API_CALL).
Related errors
- curl_multi_poll() failed, code %d.
- curl_multi failed, code %d.
- curl_multi_fdset() failed, code %d.
- curl_multi_poll() failed, code %d.
- curl_multi_fdset() failed, code %d.
AI-assisted analysis of curl/curl@527573490e (2026-08-01).
Data as JSON: /data/errors/5f86dbb4576f2c80.json.
Report an issue: GitHub.