Coronium Mobile Proxies
Proxy questions answered

Using a Proxy with cURL

Pass the proxy to curl as a URL with -x or --proxy, for example curl --proxy http://USER:PASSWORD@HOST:PORT https://api.ipify.org. For SOCKS5 with DNS on the proxy, use socks5h:// instead of http://. To avoid URL-encoding a password, put it in --proxy-user. Add -v to watch the proxy handshake.

Coronium Technical TeamSources checked 8 min read

In brief

  • -x takes a URL. With no scheme curl assumes an HTTP proxy, and with no port it assumes 1080.
  • For HTTPS websites curl opens a CONNECT tunnel through an HTTP proxy, so TLS still runs end to end.
  • socks5h:// lets the proxy resolve hostnames; socks5:// resolves them on your machine.
  • curl reads http_proxy only in lower case, and -x overrides any proxy environment variable.
  • -v prints the Proxy-Authorization header. It is Base64, not encryption, so redact it before sharing logs.

HTTP and HTTPS through a proxy

The curl manual defines -x, --proxy as [protocol://]host[:port]. If you give no protocol, or http://, curl treats it as an HTTP proxy. If you give no port, curl uses 1080. Credentials can sit in the URL, where curl URL-decodes them, or in --proxy-user (short form -U).

# HTTP proxy, HTTPS website (curl opens a CONNECT tunnel)
curl -x http://USER:PASSWORD@HOST:PORT https://api.ipify.org

# The same, with the password in its own option (no URL encoding)
curl -x http://HOST:PORT --proxy-user 'USER:PASSWORD' https://api.ipify.org

# Headers only, to see the site's response without the body
curl -sS -I -x http://USER:PASSWORD@HOST:PORT https://example.com

For an HTTPS website, curl asks the HTTP proxy to open a tunnel with the CONNECT method from RFC 9110. The proxy relays encrypted bytes and never sees the page. For a plain http:// website, curl sends the full request to the proxy instead. To force a tunnel for plain HTTP too, add -p (--proxytunnel).

With -I through an HTTP proxy, the output starts with the proxy's own HTTP/1.1 200 Connection established, followed by the website's headers. The first block is the tunnel, not the site.

All commands on this page were run with curl 8.7.1 against a local proxy that requires a username and password. Addresses in the output are documentation addresses.

SOCKS5 and socks5h

SOCKS5 is defined in RFC 1928, with username and password login in RFC 1929. curl speaks it when the proxy URL starts with socks5:// or socks5h://:

# SOCKS5, hostname resolved by the proxy
curl -x socks5h://USER:PASSWORD@HOST:PORT https://api.ipify.org

# Same thing with the dedicated option
curl --socks5-hostname HOST:PORT --proxy-user 'USER:PASSWORD' https://api.ipify.org

# Wrong SOCKS5 password, curl 8.7.1:
curl: (97) User was rejected by the SOCKS5 server (1 1).

The h decides who resolves the website's name. We logged what our test proxy received: with socks5://, curl looked up api.ipify.org itself and sent an IPv4 address; with socks5h://, it sent the hostname. Use socks5h:// so the lookup happens at the exit, matching the exit's location, and your local resolver does not see every hostname.

SOCKS5 is never the default: the manual says -x treats a proxy string with no scheme as an HTTP proxy.

Authentication and encoding

Inside a proxy URL, special characters in the username or password must be percent-encoded: @ is %40, : is %3A. With a password of p@ss:w0rd, the unencoded URL failed with curl: (5) Unsupported proxy syntax ... Port number was not a decimal number between 0 and 65535, because curl read the text after the second @ as the host. The encoded URL and --proxy-user 'lab-user:p@ss:w0rd' both worked. The proxy formats guide has the full encoding table and a converter.

curl sends Basic authentication to proxies by default. If a proxy uses another scheme, --proxy-digest, --proxy-ntlm or --proxy-anyauth, which lets curl pick a method the proxy offers, are available. Most commercial proxies, including Coronium lines, use a username and password over Basic.

One behavior that confuses scripts: with a wrong password and an https:// website, curl exits with curl: (56) CONNECT tunnel failed, response 407. With a wrong password and an http:// website, curl prints the proxy's 407 response and exits with status 0, as if it had succeeded. Add --fail, which turns it into curl: (22) The requested URL returned error: 407, or check %{http_code} with -w when scripting. The 407 guide covers every cause.

Environment variables

Without -x, curl reads proxy settings from the environment. The manual's environment section has one trap worth memorising: variables work in lower or upper case, with lower case taking precedence, except http_proxy, which curl reads only in lower case. We confirmed it: with only HTTP_PROXY set to an unused port, an http:// request went direct and succeeded.

# Lower-case http_proxy is the only form curl reads for http:// URLs
export http_proxy='http://USER:PASSWORD@HOST:PORT'
export https_proxy='http://USER:PASSWORD@HOST:PORT'
export no_proxy='.internal.example,localhost'

curl https://api.ipify.org                   # uses https_proxy
curl --noproxy api.ipify.org https://api.ipify.org   # skips it for this host
curl -x '' https://api.ipify.org             # ignores the variables for one call

# ~/.curlrc, read on every run
proxy = "http://HOST:PORT"
proxy-user = "USER:PASSWORD"

ALL_PROXY applies to every protocol, and no_proxy or --noproxy lists hosts to reach directly. -x overrides all of these, and -x '' turns them off for one command. Everything curl, the project's book, explains the order of precedence in more depth.

Reading the -v output

When a proxy connection fails, run the same command with -v. This is the start of a successful CONNECT through an authenticated HTTP proxy:

*   Trying 192.0.2.10:8080...
* Connected to 192.0.2.10 (192.0.2.10) port 8080
* CONNECT tunnel: HTTP/1.1 negotiated
* Proxy auth using Basic with user 'lab-user'
* Establish HTTP proxy tunnel to api.ipify.org:443
> CONNECT api.ipify.org:443 HTTP/1.1
> Host: api.ipify.org:443
> Proxy-Authorization: Basic bGFiLXVzZXI6cEBzczp3MHJk
> User-Agent: curl/8.7.1
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
* CONNECT phase completed
* CONNECT tunnel established, response 200

Read it in order. Connected to proves curl reached the proxy, so DNS and the port are right. Proxy auth using Basic with user shows which username curl sent. The > lines are what curl sent to the proxy, and < HTTP/1.1 200 Connection established is the proxy agreeing to open the tunnel. Anything after that is between you and the website.

The Proxy-Authorization line is your username and password in Base64, which anyone can decode. Delete it before pasting logs into a ticket or a chat.

To check just the tunnel status in a script, use -w '%{http_connect}', which prints the proxy's response code to CONNECT.

Errors seen in testing

curl proxy errors seen in testing and what they mean
OutputMeaningFirst thing to check
curl: (5) Unsupported proxy syntaxcurl could not parse the proxy URLPercent-encode @ and : in credentials
curl: (7) Failed to connectNothing answered on that host and portHost, port and whether HTTP or SOCKS port is used
curl: (56) CONNECT tunnel failed, response 407Proxy refused the credentials for an HTTPS siteUsername, password and encoding
HTTP 407 printed, exit status 0Proxy refused the credentials for an HTTP siteSame as above; add --fail in scripts
curl: (97) User was rejected by the SOCKS5 serverSOCKS5 login failedCredentials, and that the SOCKS port is used

Each row below was produced on purpose against the local test proxy with curl 8.7.1: a password with unencoded symbols, a closed port, a wrong password for an HTTPS and an HTTP site, and a wrong SOCKS5 password. When a script fails, match the message first; it usually names the layer that failed before you touch any setting.

Sources and review scope

Sources reviewed October 30, 2026. Standards, vendor documents and regulator pages were read on the date above. Where a page shows commands, they were run with curl 8.7.1 and Python Requests 2.32 against a local authenticated test proxy; addresses in the output are replaced with documentation ranges. Vendor parameters change, so confirm them in the vendor documentation linked here.

Frequently asked questions

More proxy questions

Short answers first, then the detail, with the standard or vendor document behind each claim.

Related workflows

Mobile proxies by country and carrier

Dedicated 4G and 5G carrier lines, with live stock and prices for each country and carrier.

Proxy formats explained

URL and colon formats, encoding and conversion.

SOCKS5 vs HTTP proxy

Which protocol to use, and when it matters.

Developers

REST API v3, SDK, CLI and MCP for Coronium lines.

SOCKS5 proxy guide

How SOCKS5 works and where to use it.

Fix a 407 proxy error

Every cause of a 407 and how to fix it per client.

Where to get a dedicated line

A Coronium mobile proxy is one physical device with its own SIM, rented to one customer. It connects over HTTP or SOCKS5, the IP changes by dashboard button, API link or timer, and data is not metered on dedicated lines. Brazil lines are the exception: 20 GB of data a month and a new IP on request only, with no timer. Stock and prices differ by country and carrier.