Geonode logo
Geonode Team

Geonode Team

Updated: September 2, 2026

Published: 2026-09-02

How to Set a Proxy for wget (+Examples)

wget has no `--proxy` option. That surprises people coming from curl, and it is the first thing to know. Proxies are configured through environment variables, a configuration file, or exclusion flags — and the exclusion variable, `no_proxy`, matches in a way that is narrower than most people assume. This guide covers all three methods, the SOCKS limitation nobody mentions, and how to read wget's exit codes when something goes wrong.

The disclosure and the honest steer: we are Geonode and we sell proxies, and wget is a limited client for proxy work. Its proxy support is HTTP only, with basic authentication and no SOCKS — the word "SOCKS" does not appear anywhere in its manual. If your task involves rotating addresses, sticky sessions, per-request credentials or SOCKS5, curl or a proper HTTP library will serve you better and we would rather say so than pretend otherwise. Where wget genuinely wins is recursive downloading and mirroring, and if that is your job then routing it through a proxy is straightforward. We compared the two tools properly in curl vs wget.

The Three Ways to Set a Proxy

MethodScopeBest for
Environment variablesThe shell or a single commandAd hoc use, scripts
.wgetrcYour user account, permanentlyA proxy you always use
--no-proxyOne command, to disableOverriding the above

Notice what is missing: there is no command-line flag to set a proxy. --no-proxy exists to turn one off. Setting one is done through the environment or the configuration file, and that is the whole design.

Environment Variables

The documented mechanism. From the wget manual:

Wget supports proxies for both HTTP and FTP retrievals. The standard way to specify proxy location, which Wget recognizes, is using the following environment variables

The variables are http_proxy, https_proxy, ftp_proxy and no_proxy. The manual explains: "If set, the http_proxy and https_proxy variables should contain the URLs of the proxies for HTTP and HTTPS connections respectively", and ftp_proxy "should contain the URL of the proxy for FTP connections", noting that "it is quite common that http_proxy and ftp_proxy are set to the same URL."

For a single command:

http_proxy=http://proxy.example.com:9000 \
https_proxy=http://proxy.example.com:9000 \
wget https://example.com/file.zip

For the shell session:

export http_proxy=http://proxy.example.com:9000
export https_proxy=http://proxy.example.com:9000
wget https://example.com/file.zip

Two points that cause real confusion.

https_proxy usually takes an http:// URL. The variable name refers to the destination protocol, not the protocol used to talk to the proxy. An ordinary HTTP proxy tunnelling HTTPS via CONNECT is reached over plain HTTP, so https_proxy=http://proxy:9000 is correct and looks wrong. Setting https_proxy=https://... means the connection to the proxy is itself TLS, which most proxies do not offer.

Use the lowercase names. The manual documents them in lowercase only. There is also a historical reason to prefer lowercase specifically: in CGI environments, request headers are exposed to the process as uppercase environment variables, so a client honouring HTTP_PROXY could be steered by an attacker-supplied Proxy: header — the vulnerability known as httpoxy. Sticking to lowercase avoids the whole question.

Unsetting them:

unset http_proxy https_proxy ftp_proxy

no_proxy: What It Actually Matches

The variable people get wrong, and the manual is precise about its scope:

This variable should contain a comma-separated list of domain extensions proxy should not be used for. For instance, if the value of no_proxy is .mit.edu, proxy will not be used to retrieve documents from MIT.

"Domain extensions" is the operative phrase. It is suffix matching on hostnames.

export no_proxy=".example.com,.internal,localhost,127.0.0.1"

What this means in practice:

A leading dot matches subdomains. .example.com excludes www.example.com and api.example.com. Whether it also excludes the bare example.com varies by implementation, so if you need both, list both.

Whitespace is not tolerated. example.com, other.com may fail to match the second entry because the leading space becomes part of the string. Use no spaces after commas — this is the most common no_proxy bug by a wide margin.

CIDR ranges are not documented. no_proxy=10.0.0.0/8 is honoured by some tools and is not part of what the wget manual describes. Do not rely on it. List the specific hosts, or use --no-proxy for those commands.

Ports are not part of the documented matching either. example.com:8080 may not behave as you expect.

* is not a wildcard in the general case. Some implementations accept no_proxy=* to mean "never proxy"; the cleaner way to express that with wget is --no-proxy on the command, or use_proxy = off in .wgetrc.

For a single command that should bypass the proxy regardless of the environment, the manual is unambiguous about --no-proxy:

Don't use proxies, even if the appropriate *_proxy environment variable is defined.

wget --no-proxy https://internal.example.com/build.tar.gz

That is the reliable escape hatch, and it is better than fighting with no_proxy syntax for one-off exclusions.

Authentication

Two forms, with a meaningful security difference between them.

Command-line options, documented as: "Specify the username user and password password for authentication on a proxy server. Wget will encode them using the basic authentication scheme."

wget --proxy-user=myuser --proxy-password=mypass https://example.com/file.zip

Embedded in the proxy URL:

export http_proxy=http://myuser:mypass@proxy.example.com:9000

Both work. Both expose the password.

The manual notes for the option form that "security considerations similar to those with --http-password pertain here as well", and the concern is concrete: command-line arguments are visible in the process list to any user on the machine, and they land in shell history. The URL form has the same problem plus appearing in environment dumps and in any error output you paste into a bug report.

The safer arrangement is .wgetrc with restricted permissions, covered next. If you must use the environment, at least keep the credentials out of your shell history:

read -rs PROXY_PASS
export http_proxy="http://myuser:${PROXY_PASS}@proxy.example.com:9000"

Also note the encoding requirement: basic authentication means the credentials are base64-encoded, not encrypted. Over a plain HTTP connection to the proxy they are effectively in clear text on your local network segment. That is a property of proxy authentication generally rather than of wget.

And if your password contains @, : or /, percent-encode it before putting it in a URL, or the URL parser will split in the wrong place.

Persistent Configuration in .wgetrc

For a proxy you always use, put it in ~/.wgetrc:

use_proxy = on
http_proxy = http://proxy.example.com:9000/
https_proxy = http://proxy.example.com:9000/
proxy_user = myuser
proxy_password = mypass

Then restrict the permissions, because the file now contains a password:

chmod 600 ~/.wgetrc

This is the better place for credentials than the environment or the command line: it is not in the process list, not in shell history, and not in an environment dump.

use_proxy = off disables proxying globally while leaving the settings in place, which is convenient when you want to toggle rather than delete.

There is also a system-wide /etc/wgetrc, which is worth knowing about for a specific reason: if wget is using a proxy you did not configure, check there before concluding something is haunted. Precedence runs system file, then user file, then environment variables, then command-line options — with later sources overriding earlier ones.

wget Has No SOCKS Support

Worth stating plainly because it is not stated plainly anywhere else, and because it is the reason a lot of wget-and-proxy questions have no answer.

The wget manual documents proxy support for HTTP, HTTPS and FTP retrievals. The word "SOCKS" does not appear in it at all. There is no --socks5 option, no socks_proxy environment variable, and no configuration setting for it.

If your proxy is SOCKS, you have three options:

Use curl instead, which supports SOCKS4, SOCKS4a and SOCKS5 natively:

curl -x socks5h://proxy.example.com:1080 -O https://example.com/file.zip

Note the socks5h scheme rather than socks5: it sends the hostname to the proxy for resolution rather than resolving locally, which avoids leaking your DNS queries.

Wrap wget in a redirector such as proxychains, which intercepts network calls at the library level and routes them through SOCKS. This works, with the caveat that it only affects dynamically linked programs.

Ask your provider for an HTTP endpoint. Most commercial proxy services offer both, and using the HTTP one is far simpler than either workaround.

For most people the honest answer is the first: if the job needs SOCKS, use a client that supports it.

Troubleshooting by Exit Code

wget's exit codes are more specific than most tools', and reading them saves guessing. From the manual:

CodeMeaning
0No problems occurred
1Generic error code
2Parse error — command-line options, .wgetrc or .netrc
3File I/O error
4Network failure
5SSL verification failure
6Username/password authentication failure
7Protocol errors
8Server issued an error response

The manual adds that "with the exceptions of 0 and 1, the lower-numbered exit codes take precedence over higher-numbered ones, when multiple types of errors are encountered."

Mapping these to proxy problems:

Exit 4 (network failure) — cannot reach the proxy at all. Check the host and port, and confirm with nc -zv proxy.example.com 9000.

Exit 6 (authentication failure) — the proxy answered and rejected your credentials. Check the username and password, and check whether the provider uses an IP allowlist you have not updated.

Exit 5 (SSL verification failure) — often the proxy intercepting TLS, or a corporate certificate authority your system does not trust. Do not reach for --no-check-certificate as a fix; find out why verification failed first.

Exit 8 (server error response) — you reached the target through the proxy and it returned a 4xx or 5xx. The proxy is working; the request is the problem.

Exit 2 (parse error) — frequently a malformed proxy URL or a .wgetrc syntax problem. Check for unencoded special characters in a password.

For anything unclear, -d produces debug output showing the connection sequence:

wget -d https://example.com/file.zip 2>&1 | head -40

That output shows whether wget contacted the proxy at all, which resolves the most common ambiguity immediately — whether your configuration took effect.

Verifying the Proxy Is Actually Being Used

The most common wget-and-proxy question is not how to set one, but whether the setting took effect. Three checks answer it.

Ask a service what address it sees. The simplest end-to-end confirmation:

wget -qO- https://api.ipify.org; echo

Run it with and without the environment variables set. If the address does not change, wget is not using the proxy and nothing else you do to the target URL will matter.

Read the debug output. -d prints the connection sequence, and the first lines tell you which host wget resolved and connected to:

wget -d -O /dev/null https://example.com 2>&1 | grep -iE 'connecting|resolving|proxy'

If it says it is connecting to your target directly, the proxy configuration is not being applied — check the variable names, check no_proxy, and check for a use_proxy = off in either wgetrc file.

Check both protocols separately. A very common half-configured state is http_proxy set and https_proxy unset, which produces the confusing result that some URLs are proxied and some are not. Test one of each:

wget -qO- http://api.ipify.org; echo
wget -qO- https://api.ipify.org; echo

Different answers mean one of the two variables is missing.

And confirm the exit address matches what you asked for. For geo-targeted proxies, checking the address is not enough — verify that the content differs as it should. An IP lookup reporting the right country while the page shows you your home content means the targeting is not landing where it matters, which is the silent failure we described in why testing proxies matters.

HTTPS Through a Proxy

Three things behave differently from plain HTTP and are worth knowing before you debug the wrong layer.

The proxy tunnels rather than fetches. For an HTTPS URL, wget issues a CONNECT and the proxy relays encrypted bytes. It cannot read or cache the content, which means proxy-side caching does nothing for HTTPS.

Some proxies restrict CONNECT to port 443. If HTTP works and HTTPS does not, that restriction is a likely cause — particularly for HTTPS on a non-standard port.

Certificate verification is against the target, not the proxy. A verification failure through a proxy that works directly usually means TLS interception, which means someone is decrypting your traffic. In a managed corporate environment that may be expected. Anywhere else it deserves an explanation before you work around it.

For downloads specifically, two further habits matter through a metered proxy. Use -c so an interrupted transfer resumes rather than restarting — you pay for every byte, and paying twice for the same file is avoidable. And set a quota with -Q if you are running an unattended recursive job, because recursion plus metered bandwidth is the classic way to discover a large invoice.

People Also Ask

How do I set a proxy for wget?

Through environment variables — export http_proxy=http://proxy.example.com:9000 and the same for https_proxy — or permanently in ~/.wgetrc. There is no command-line flag to set a proxy; --no-proxy exists only to disable one.

Why is wget ignoring my proxy settings?

Check three things: that you used lowercase variable names, that no_proxy does not match your target (a stray space after a comma is the usual culprit), and that use_proxy is not set to off in /etc/wgetrc or ~/.wgetrc. Run wget -d to see whether it contacts the proxy at all.

How does no_proxy work in wget?

It takes a comma-separated list of domain extensions to bypass, matched as hostname suffixes — .example.com excludes subdomains of example.com. Do not put spaces after the commas, and do not rely on CIDR ranges or port matching, neither of which is documented. For one-off exclusions, --no-proxy is more reliable.

Does wget support SOCKS proxies?

No. The manual documents HTTP, HTTPS and FTP proxy support and never mentions SOCKS. There is no option or environment variable for it. Use curl with socks5h://, wrap wget in proxychains, or ask your provider for an HTTP endpoint.

How do I use wget with a proxy that needs a password?

--proxy-user=user --proxy-password=pass, or embed credentials in the proxy URL. Both expose the password — in the process list and shell history for the first, in environment dumps for the second. Prefer ~/.wgetrc with chmod 600, which keeps credentials out of both.

Why does https_proxy use an http:// URL?

Because the variable names the destination protocol, not the protocol used to reach the proxy. An ordinary HTTP proxy tunnels HTTPS through CONNECT and is itself contacted over plain HTTP. https_proxy=https://... means TLS to the proxy itself, which most proxies do not offer.

How do I bypass the proxy for one wget command?

wget --no-proxy URL. The manual describes it as not using proxies "even if the appropriate *_proxy environment variable is defined", so it overrides everything without needing to edit no_proxy.

What does wget exit code 6 mean?

Username or password authentication failure. With a proxy configured, that usually means your proxy credentials were rejected — or that your provider uses an IP allowlist and your current address is not on it. Compare against exit 4, which means you could not reach the proxy at all.

Wrapping Up

wget's proxy support is configuration-driven rather than flag-driven, and once you know that, the rest is short: lowercase environment variables for ad hoc use, ~/.wgetrc with restricted permissions when you always use the same proxy and need credentials in it, and --no-proxy when you want to skip it for one command.

The two things that waste the most time are both avoidable. no_proxy matches domain suffixes and nothing more, so spaces after commas, CIDR ranges and port suffixes all fail quietly — when an exclusion is not working, use --no-proxy rather than debugging the syntax. And https_proxy almost always takes an http:// URL, because the name refers to where you are going rather than how you reach the proxy.

The limitation worth planning around is SOCKS, which wget simply does not do. If that is your requirement, the answer is a different tool rather than a workaround — and for anything involving rotation, sessions or per-request credentials, that is true more broadly. wget is excellent at recursive mirroring, and that is the job worth routing through a proxy with it.

How to Set a Proxy for wget: Env Vars no_proxy and .wgetrc | Geonode