Skip to content

Proxied connections to IPv6 hostnames fail with CURLE_OUT_OF_MEMORY #22382

Description

@RMMoreton

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions