CURLINFO_PROXY_ERROR(3)

πŸ’… CURLINFO_PROXY_ERROR β€” the "bestie, what actually went wrong with the proxy" award πŸŽ€

Okay so first things first: this is a page from the libcurl manual, and the function we're simping over is CURLINFO_PROXY_ERROR. If your transfer faceplanted with a CURLE_PROXY error and you're sitting there like "πŸ§β€β™€οΈ okay but which proxy thing", this is the glow-up you need. It hands you the receipts. Periodt.


🌸 NAME 🌸

CURLINFO_PROXY_ERROR β€” the detailed (SOCKS) proxy error, aka the reason your proxy ghosted you, spelled out properly πŸ’”


✨ SYNOPSIS ✨

#include <curl/curl.h>

typedef enum {
  CURLPX_OK,
  CURLPX_BAD_ADDRESS_TYPE,
  CURLPX_BAD_VERSION,
  CURLPX_CLOSED,
  CURLPX_GSSAPI,
  CURLPX_GSSAPI_PERMSG,
  CURLPX_GSSAPI_PROTECTION,
  CURLPX_IDENTD,
  CURLPX_IDENTD_DIFFER,
  CURLPX_LONG_HOSTNAME,
  CURLPX_LONG_PASSWD,
  CURLPX_LONG_USER,
  CURLPX_NO_AUTH,
  CURLPX_RECV_ADDRESS,
  CURLPX_RECV_AUTH,
  CURLPX_RECV_CONNECT,
  CURLPX_RECV_REQACK,
  CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED,
  CURLPX_REPLY_COMMAND_NOT_SUPPORTED,
  CURLPX_REPLY_CONNECTION_REFUSED,
  CURLPX_REPLY_GENERAL_SERVER_FAILURE,
  CURLPX_REPLY_HOST_UNREACHABLE,
  CURLPX_REPLY_NETWORK_UNREACHABLE,
  CURLPX_REPLY_NOT_ALLOWED,
  CURLPX_REPLY_TTL_EXPIRED,
  CURLPX_REPLY_UNASSIGNED,
  CURLPX_REQUEST_FAILED,
  CURLPX_RESOLVE_HOST,
  CURLPX_SEND_AUTH,
  CURLPX_SEND_CONNECT,
  CURLPX_SEND_REQUEST,
  CURLPX_UNKNOWN_FAIL,
  CURLPX_UNKNOWN_MODE,
  CURLPX_USER_REJECTED,
  CURLPX_LAST /* never use */
} CURLproxycode;

CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_PROXY_ERROR, long *detail);

Like, look at that enum. Thirty-five whole moods. CURLPX_LAST is literally marked /* never use */ so pls respect the boundary bestie πŸ™ˆ


πŸ¦‹ DESCRIPTION πŸ¦‹

So here's the tea β˜• β€” you pass in a pointer to a long, and if your most recent transfer returned a CURLE_PROXY error, that long gets filled with a detailed error code. And that code matches up with one of the CURLproxycode values from the enum above. Chef's kiss. πŸ‘‘

Heads up though: if no response code was available, the error code is zero (CURLPX_OK). So a zero does not necessarily mean "slay, everything was fine" β€” it means nothing came back. Read it carefully, iykyk πŸ’€

🌈 PROTOCOLS 🌈

This functionality affects all supported protocols. Every single one. No gatekeeping. 🫢


πŸ“ EXAMPLE πŸ“

The moment you've been waiting for β€” actual code, no notes:

int main(void)
{
  CURL *curl = curl_easy_init();
  if(curl) {
    CURLcode result;
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");

    curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://127.0.0.1");
    result = curl_easy_perform(curl);
    if(result == CURLE_PROXY) {
      long proxycode;
      result = curl_easy_getinfo(curl, CURLINFO_PROXY_ERROR, &proxycode);
      if(!result && proxycode)
        printf("The detailed proxy error: %ld\n", proxycode);
    }
    curl_easy_cleanup(curl);
  }
}

Notice the vibe check: it only bothers asking for the detail after result == CURLE_PROXY, and it only prints when !result && proxycode. That's the "don't @ me unless there's actual drama" pattern. Iconic. πŸ’…


⭐ AVAILABILITY ⭐

Added in curl 7.73.0 β€” so she's been around, she's established, she's not new here. πŸŽ€


πŸ’œ RETURN VALUE πŸ’œ

curl_easy_getinfo(3) returns a CURLcode indicating success or error.

CURLE_OK (0) means everything was OK β€” non-zero means an error occurred, see libcurl-errors(3).

Translation: 0 = we're so back, non-zero = it's over 😭


πŸ”₯ SEE ALSO πŸ”₯

Go read them, they're all besties of this page 🫢


That's the whole page, bestie! Sourced straight from the libcurl manual, dated 2026-10-12 β€” go off, debug your proxy, and remember: CURLPX_OK doesn't always mean what you think it means. πŸ’–βœ¨πŸ¦‹

πŸ“¦ where this page comes from