🎁 Free Trial: Register now to claim 1GB Global Traffic (Valid 7 days).Get Free Traffic

Proxy Environment Variables with curl: HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, and NO_PROXY

Published
Reading Time5 min read

Key Takeaways

A standards-backed guide to configuring and auditing curl proxy environment variables without silently bypassing routes or leaking credentials.

curl can select a proxy from environment variables even when a command does not contain --proxy. That convenience can also create hard-to-see routing differences between a developer shell, CI worker, container, and production process.
This guide explains curl's proxy-variable precedence, why http_proxy is intentionally lowercase-only, how NO_PROXY matching works, and how to verify the effective route without claiming that an unexecuted example succeeded.

Direct answer

For curl:
  • use lowercase http_proxy for HTTP target URLs;
  • use HTTPS_PROXY or https_proxy for HTTPS target URLs;
  • use ALL_PROXY only as a fallback when no protocol-specific variable is set;
  • use NO_PROXY or no_proxy for destinations that must connect directly;
  • expect an explicit --proxy option to override proxy-selection environment variables;
  • do not rely on uppercase HTTP_PROXY, because curl rejects it to avoid CGI-derived environment-variable attacks.
These rules describe curl and libcurl. Other tools and language runtimes can implement different case handling, precedence, wildcard behavior, and CIDR support.

The four variables that matter most

Variable
Purpose
Important boundary
http_proxy
Proxy for HTTP target URLs
curl accepts this name in lowercase only
HTTPS_PROXY / https_proxy
Proxy for HTTPS target URLs
This selects the proxy; it does not mean the proxy connection itself is necessarily TLS
ALL_PROXY / all_proxy
Fallback proxy for protocols without a specific variable
A protocol-specific variable takes precedence
NO_PROXY / no_proxy
Comma-separated direct-connect exclusions
Matching details are client-specific; verify with the exact curl version in use
The target URL scheme chooses the protocol-specific variable. For example, an https:// target causes curl to consider https_proxy or HTTPS_PROXY, even when the selected proxy URL begins with http:// and curl uses HTTP CONNECT to establish a tunnel.

Why http_proxy is lowercase-only

CGI maps incoming HTTP request headers to environment variables whose names begin with HTTP_. An incoming Proxy header can therefore become HTTP_PROXY in a CGI process environment.
If a command-line HTTP client trusted uppercase HTTP_PROXY, an external request header could influence the outbound proxy used by a server-side script. curl avoids this class of problem by accepting http_proxy only in lowercase. RFC 3875 defines the CGI conversion of HTTP headers into HTTP_ meta-variables, and curl's official documentation explains the lowercase-only exception.
Operational rule: do not “fix” a missing curl proxy by exporting uppercase HTTP_PROXY. Set lowercase http_proxy, or use an explicit --proxy argument in a controlled command.

Precedence: make the chosen route visible

Start by inspecting only the names and non-secret endpoint fields you intend to use:
printf 'http_proxy=%s\n' "${http_proxy:-<unset>}" printf 'https_proxy=%s\n' "${https_proxy:-${HTTPS_PROXY:-<unset>}}" printf 'all_proxy=%s\n' "${all_proxy:-${ALL_PROXY:-<unset>}}" printf 'no_proxy=%s\n' "${no_proxy:-${NO_PROXY:-<unset>}}"
Do not print these variables in shared logs when they contain usernames, passwords, tokens, or account identifiers.
A controlled curl template can then make the explicit override clear:
curl --silent --show-error --fail-with-body \ --proxy "http://PROXY_HOST:PORT" \ --proxy-user "${PROXY_USER}:${PROXY_PASS}" \ --connect-timeout 10 \ --max-time 30 \ "https://example.com/"
This content operation did not execute the command and records no observed status, route, latency, or compatibility result. Replace placeholders with account-approved values and test only a target you are authorized to access.
To force curl not to use a proxy selected from the environment for one command, the curl manual documents setting the proxy option to an empty value:
curl --proxy "" "https://example.com/"
Use this as a diagnostic boundary, not as a permanent workaround for an unexplained environment configuration.

NO_PROXY matching and common mistakes

NO_PROXY is a comma-separated exclusion list. curl supports:
  • exact hostnames;
  • domain suffix entries;
  • a single * to disable proxy use for all destinations;
  • numerical IP addresses;
  • CIDR network notation in curl 7.86.0 and later.
Example:
export NO_PROXY="localhost,127.0.0.1,.internal.example,192.168.0.0/16"
A leading dot such as .internal.example is intended to match hosts within that domain. Do not assume shell globs such as *.internal.example behave identically across clients.
Before deploying an exclusion list, record:
  • the exact curl version;
  • the target hostname as curl receives it;
  • whether a port is present;
  • whether the destination is an IPv4 address, IPv6 address, or hostname;
  • whether the route should be direct for every environment or only one worker class.
A broad NO_PROXY=* can silently bypass all proxy routing. Treat it as a temporary diagnostic value and remove it explicitly.

Keep credentials out of shared environment dumps

Proxy URLs may contain username:password@host. Environment variables can be exposed through debug output, crash reports, CI configuration, process inspection, support bundles, or accidental env dumps.
Prefer separate secret injection for the password and a non-secret variable for the proxy endpoint. Where the client supports structured proxy authentication, keep credentials out of the URL authority section. Never commit real proxy variables to .env examples, container images, shell profiles in shared repositories, or workflow logs.
When collecting evidence, record a sanitized form:
curl version: Operating system/container image: Target scheme: http | https Selected variable name: http_proxy | HTTPS_PROXY | ALL_PROXY | explicit --proxy Proxy scheme: http | https | socks5 | socks5h Proxy host: approved hostname or redacted Proxy port: NO_PROXY value: sanitized Expected route: proxy | direct Observed exit IP: sanitized and authorized HTTP status or curl exit code: Timestamp and timezone:
Do not include the proxy password, Proxy-Authorization value, full account username, session token, or raw environment dump.

Diagnose route disagreements in a fixed order

  1. Check explicit command options. --proxy, --noproxy, and related options can override environment behavior.
  1. List relevant variable names. Check lowercase and uppercase forms without exposing secret values.
  1. Confirm the target scheme. An HTTPS target uses the HTTPS-specific proxy variable, not http_proxy.
  1. Inspect NO_PROXY. Look for *, suffix entries, IPs, CIDR blocks, and inherited container or CI settings.
  1. Compare environments. Interactive shells, service managers, containers, and CI jobs often inherit different variables.
  1. Run one authorized direct-versus-proxy comparison. Record curl exit code, HTTP status, and sanitized route evidence.
  1. Remove temporary overrides. Do not leave NO_PROXY=*, --proxy "", verbose tracing, or test credentials in production configuration.
If the proxy hostname resolves differently across environments, continue with the proxy DNS troubleshooting guide. For account-specific endpoint, port, GEO, and session settings, use the BytesFlows proxy setup guide and treat the current Dashboard as the final source of account configuration.

Limitations

  • This page documents curl behavior, not a universal proxy-variable standard.
  • CIDR exclusions require curl 7.86.0 or later.
  • A successful connection does not prove the requested geography, session behavior, target permission, or production suitability.
  • HTTPS_PROXY selects the proxy used for an HTTPS target; it does not by itself prove TLS is used between the client and proxy.
  • Environment-variable inspection can expose secrets. Sanitize before logging or sharing.
  • No BytesFlows production account, endpoint, benchmark, target compatibility, or route behavior was tested during this content operation.

Next step

Use one approved test target and compare the sanitized result with and without the intended proxy variable. Record the curl exit code, HTTP status, and sanitized exit-IP or routing evidence, then compare the endpoint, port, GEO, and session settings with the BytesFlows proxy setup guide and the current Dashboard before adding the configuration to a service, container, or CI environment.

Evidence

  • curl official manual: --proxy, --noproxy, environment-variable behavior, direct-connection overrides, URL decoding, and CIDR details.
  • RFC 3875, CGI/1.1: HTTP request headers are mapped to HTTP_ meta-variables in CGI environments.
The command examples are review templates. They were not executed in this operation and must not be cited as verified BytesFlows results.
AV
Engineering Team ReviewedBenchmarked & Peer Reviewed

Alex Vance

Lead Proxy Network Architect

Reviewed by the BytesFlows engineering team. Examples are written for compliant public-web data collection, QA, SEO monitoring, and market research workflows. Results can vary by target site, country, client runtime, and request rate.