If curl tries to connect to localhost regardless of the URL you gave it, the VPN is the wrong place to start. A local HTTP or SOCKS proxy can be the intended first connection, even when the service you want is somewhere else entirely. If that proxy is no longer running, the localhost attempt fails before curl ever reaches the destination. A proxy response is also not proof that the destination answered.

Work these steps in order and stop at the first one that changes the first connection attempt.

Read curl's own proxy rules first

curl reads protocol-specific proxy variables such as https_proxy and HTTPS_PROXY, plus ALL_PROXY when no protocol-specific value applies. Inspect the environment of the shell, service or task that actually launches curl, not the one in your current terminal. A CI job, a systemd unit and an interactive shell can inherit three different sets. Guessing from the visible shell is how this investigation wastes an afternoon.

One exception is worth memorizing. curl accepts http_proxy in lowercase only; uppercase HTTP_PROXY is ignored, which is why the same environment behaves differently in other tools.

Read the values privately, because a proxy URL often carries credentials.

Then check the default curl configuration file for proxy or connection overrides, and confirm which executable you are actually running. A shell alias, a function or a wrapper script can add options that never appear on your command line.

Compare three invocations with TLS on

Use one approved diagnostic destination and the same binary for all three runs.

curl -v https://service.corp.example/status
curl -q -v https://service.corp.example/status
curl -q --proxy '' -v https://service.corp.example/status

-q suppresses the default curlrc and has to be the first parameter on the line to work. It does not remove proxy environment variables, which surprises people who expect it to. The third form adds an empty --proxy value, overriding an environment-requested proxy for that invocation only. Compare the first connection attempt in each output, not the final status code.

Verbose output can expose headers, tokens and proxy credentials, so keep it local and read excerpts before sharing them.

What each result rules out

If omitting the default configuration changes the connection, the configuration file is the source. If explicitly disabling the inherited proxy changes it, the environment variable is the source. If neither changes it and localhost still appears, look at command-line connection overrides, hostname resolution and the selected executable. Each of those has a different fix, and none of them is a routing change.

Custom library loading or injected network behaviour is a later layer, and an environment variable alone is not proof of it.

Keep the proxy decision apart from the VPN

Once curl chooses a direct destination, the operating system still routes that connection. Disabling an application proxy does not disable the VPN's route or its filtering policy. Run direct-access comparisons only where that diagnostic is authorized. A test that quietly bypasses policy is not a valid result, it is an incident.

If a local proxy is required, restore its service and address instead of deleting its settings.

If only selected private destinations need direct access, add a narrow approved exclusion and keep the proxy for everything else. Preserve the first error from the chosen path, because a localhost refusal, a proxy CONNECT rejection, a certificate failure and an authorization error identify four different stages.

Ebitabo ebifaananyi