I did this
In one terminal, run netcat -6 -l -p 8421.
In another terminal, run the following:
int main(int argc, char* argv[]) {
curl_global_init(CURL_GLOBAL_ALL);
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_PROXY, "localhost:8421");
// This is from dig +short AAAA google.com. Any IPv6 address will demonstrate the problem.
curl_easy_setopt(curl, CURLOPT_URL, "http://[2607:f8b0:4006:805::200e]");
CURLcode res = curl_easy_perform(curl);
if (res) {
printf("curl_easy_perform failed: %s\n", curl_easy_strerror(res));
} else {
printf("curl_easy_perform succeeded");
}
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}
Alternatively, you can just run curl -x localhost:8421 -v http://[2607:f8b0:4006:805::200e] and you'll see the same error with slightly different output.
I expected the following
Curl should hang waiting for a response from the fake netcat proxy. Instead, I see:
* timeout on name lookup is not supported
* Host localhost:8421 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:8421...
* Established connection to localhost (::1 port 8421) from ::1 port 57124
* using HTTP/1.x
* Connection #0 to host localhost:8421 left intact
curl_easy_perform failed: Out of memory
It's not actually out of memory, though. The issue is in http.c, around line 2127:
if(data->state.origin->user_hostname != data->state.origin->hostname) {
uc = curl_url_set(h, CURLUPART_HOST, data->state.origin->hostname, 0);
if(uc) {
curl_url_cleanup(h);
return CURLE_OUT_OF_MEMORY;
}
}
Putting a breakpoint there shows that user_hostname and hostname are not equal. So it attempts to set the host part of h to data->state.origin->hostname. But data->state.origin->hostname is equal to the string 2607:f8b0:4006:805::200e (i.e. it has no [] around it) which is not a valid host. So the call to curl_url_set fails and returns CURLE_OUT_OF_MEMORY.
curl/libcurl version
libcurl/8.21.0-DEV BoringSSL zlib/1.3.2.1 brotli/1.0.3840 c-ares/1.21.0 nghttp2/1.51.0
operating system
Linux 6.18.14-1rodete4-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.18.14-1rodete4 (2026-06-15) x86_64 GNU/Linux
I did this
In one terminal, run
netcat -6 -l -p 8421.In another terminal, run the following:
Alternatively, you can just run
curl -x localhost:8421 -v http://[2607:f8b0:4006:805::200e]and you'll see the same error with slightly different output.I expected the following
Curl should hang waiting for a response from the fake
netcatproxy. Instead, I see:It's not actually out of memory, though. The issue is in http.c, around line 2127:
Putting a breakpoint there shows that
user_hostnameandhostnameare not equal. So it attempts to set the host part ofhtodata->state.origin->hostname. Butdata->state.origin->hostnameis equal to the string2607:f8b0:4006:805::200e(i.e. it has no[]around it) which is not a valid host. So the call tocurl_url_setfails and returnsCURLE_OUT_OF_MEMORY.curl/libcurl version
libcurl/8.21.0-DEV BoringSSL zlib/1.3.2.1 brotli/1.0.3840 c-ares/1.21.0 nghttp2/1.51.0operating system
Linux 6.18.14-1rodete4-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.18.14-1rodete4 (2026-06-15) x86_64 GNU/Linux