curl/curl ยท critical
error allocating transfer structs
Error message
error allocating transfer structs
What it means
Printed in http2-download.c:213-216 when calloc(num_transfers, sizeof(*trans)) returns NULL, i.e. the allocation of the array of struct transfer descriptors failed. This is a hard out-of-memory condition: the program cannot proceed and jumps to the cleanup label. num_transfers comes from argv[1] (clamped to 1..1000, default 3).
Source
Thrown at docs/examples/http2-download.c:214
int still_running = 0; /* keep number of running handles */
int num_transfers;
if(argc > 1) {
/* if given a number, do that many transfers */
num_transfers = atoi(argv[1]);
if((num_transfers < 1) || (num_transfers > 1000))
num_transfers = 3; /* a suitable low default */
}
else
num_transfers = 3; /* a suitable low default */
result = curl_global_init(CURL_GLOBAL_ALL);
if(result != CURLE_OK)
return (int)result;
trans = calloc(num_transfers, sizeof(*trans));
if(!trans) {
fprintf(stderr, "error allocating transfer structs\n");
goto error;
}
/* init a multi stack */
multi = curl_multi_init();
if(!multi)
goto error;
for(i = 0; i < num_transfers; i++) {
if(setup(&trans[i], i)) {
goto error;
}
/* add the individual transfer */
curl_multi_add_handle(multi, trans[i].curl);
}
curl_multi_setopt(multi, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);View on GitHub (pinned to 527573490e)
Solutions
- Reduce num_transfers (the first CLI argument) to a smaller value.
- Raise available memory / container memory limits.
- Check errno (ENOMEM) and free other allocations before retrying.
- On 32-bit, ensure num_transfers * sizeof(*trans) does not overflow.
Example fix
// before
trans = calloc(num_transfers, sizeof(*trans));
if(!trans) {
fprintf(stderr, "error allocating transfer structs\n");
goto error;
}
// after - fall back to a smaller batch and report the cause
trans = calloc(num_transfers, sizeof(*trans));
if(!trans) {
fprintf(stderr, "error allocating %d transfer structs: %s\n",
num_transfers, strerror(errno));
goto error;
} Defensive patterns
Strategy: validation
Validate before calling
/* Bound and overflow-check the count before calloc. */ int n = (argc > 1) ? atoi(argv[1]) : 3; if(n < 1 || n > 1000) n = 3; /* clamp like the example */ if((size_t)n > SIZE_MAX / sizeof(struct transfer)) return 1; /* overflow */
Type guard
/* Guard: num_transfers is a positive, bounded integer. */
static int sane_count(int n) { return n >= 1 && n <= 1000; }
if(!sane_count(num_transfers)) num_transfers = 3; Try / catch
trans = calloc((size_t)num_transfers, sizeof(*trans));
if(!trans) {
fprintf(stderr, "error allocating transfer structs\n");
goto error; /* nothing to free here; clean up multi/global downstream */
} Prevention
- Clamp user-supplied transfer counts to a sane maximum (the example uses [1,1000]).
- Guard against size_t overflow: check n <= SIZE_MAX / sizeof(struct) before calloc.
- On calloc failure, degrade gracefully (fewer parallel transfers) rather than aborting.
- Keep a single cleanup label so every successfully allocated resource is freed in the error path.
When it happens
Trigger: malloc/calloc returning NULL due to memory exhaustion; requesting an extremely large num_transfers near the upper clamp of 1000 on a constrained system; running under cgroup memory limits that deny the allocation; calloc overflow guard tripping (sizeof(*trans) * num_transfers exceeds SIZE_MAX).
Common situations: Container/pod with low memory limits; embedded device with little RAM; passing a huge number as the first argument; running alongside a memory-hungry process; 32-bit build where address space is limited.
Related errors
- curl_easy_perform() failed: %s
- error: could not open file %s for writing: %s
- Failed to create output file for push
- failed
- error allocating transfer structs
AI-assisted analysis of curl/curl@527573490e (2026-08-01).
Data as JSON: /data/errors/3472e21381fc0ae8.json.
Report an issue: GitHub.