wget takes a proxy the Unix way, through environment variables it already reads, which makes the common case a one-line export and the edge cases a matter of knowing which variable wins. This guide covers proxies with wget end to end: the http_proxy and https_proxy variables, setting a proxy for a single command with -e, authentication, the no_proxy bypass, why SOCKS needs a wrapper, and verifying the exit IP so you know the download actually went through the proxy.
We run a proxy network and a live proxy checker, so the wget proxy issue we see most is a proxy that is set but not used, almost always because use_proxy is off or a no_proxy rule is quietly matching the target. Every example below is runnable on the standard GNU wget. Where one needs a live proxy, pull a fresh one from our free proxy API, which returns recently checked endpoints with no key.
How do you use a proxy with wget?
Export the proxy into the environment variables wget reads, then use wget as normal:
export https_proxy="http://203.0.113.7:8080"
export http_proxy="http://203.0.113.7:8080"
wget https://example.com/file.zip
The variable name is the scheme of the URL you are fetching, not the proxy: https_proxy handles https:// downloads and http_proxy handles http:// ones. A plain HTTP proxy carries HTTPS through a CONNECT tunnel, so pointing https_proxy at an http:// proxy is the normal, correct combination even though it looks mismatched.
Setting a proxy for one command only
If you do not want to change your shell environment, pass the proxy inline with -e (the same as --execute), which injects a .wgetrc command for that run:
wget -e use_proxy=yes -e https_proxy=http://203.0.113.7:8080 https://example.com/file.zip
use_proxy=yes is the switch that turns proxying on. When you set the environment variables directly it is implied, but with the -e form it is worth stating so the run does not silently go direct.
https:// URL
scheme decides the variable
https_proxy set?
and use_proxy on
no_proxy match?
if yes, go direct
Fetch via proxy
CONNECT tunnel for HTTPS
Authentication
For a paid proxy, put the credentials in the URL inside the variable, user:pass@host:port:
export https_proxy="http://user:pass@203.0.113.7:8080"
wget https://example.com/file.zip
Or keep them out of the URL and pass them as flags, which is cleaner when the password has characters that are awkward to encode:
wget --proxy-user=myuser --proxy-password='p@ss:word' \
-e use_proxy=yes -e https_proxy=http://203.0.113.7:8080 \
https://example.com/file.zip
A wrong or missing login returns HTTP 407 Proxy Authentication Required, which confirms the proxy is alive and only the credentials are off.
The no_proxy bypass
no_proxy is the list of hosts that should skip the proxy and connect directly, which keeps local and internal traffic off it:
export no_proxy="localhost,127.0.0.1,.internal.example.com"
It is also a common cause of "the proxy is ignored": a broad entry here can match your real target and send that download direct on your own IP. When a proxied wget unexpectedly shows your own address, check no_proxy first.
wget has no SOCKS, use a wrapper
wget speaks HTTP and HTTPS proxies only. To push it through a SOCKS proxy, wrap it in a tool that redirects its connections, most commonly proxychains:
proxychains wget https://example.com/file.zip
We cover that setup in how to use proxychains. For plain wget without a wrapper, pull the HTTP or HTTPS entries from a proxy list rather than the SOCKS ones.
Rotating across a pool
wget has no built-in rotation, but a shell loop gives you the same effect: pick a fresh proxy per attempt and retry on the next when one fails.
#!/bin/bash
mapfile -t POOL < <(curl -s "https://hproxy.com/api/proxy-list?format=txt&protocol=http&recent=true&limit=50")
fetch() {
local url="$1" tries=4
for _ in $(seq "$tries"); do
local p="${POOL[RANDOM % ${#POOL[@]}]}"
if wget -q -e use_proxy=yes -e https_proxy="http://$p" -O "$(basename "$url")" "$url"; then
return 0
fi
done
echo "all $tries proxies failed for $url" >&2
return 1
}
fetch "https://example.com/file.zip"
The load-bearing part is the same as any rotation loop: a different exit per attempt, because retrying a dead proxy just wastes the try. The pool comes straight from our free proxy API as plain text.
Verify the exit IP
Confirm the request went through the proxy and not direct. wget -qO- prints the body to standard output, so an IP echo is a one-liner:
wget -qO- -e use_proxy=yes -e https_proxy=http://203.0.113.7:8080 https://httpbin.org/ip
If the address it prints is your own, the proxy was not used, which points at use_proxy being off or a no_proxy match. When you need more than the exit address, wget --debug prints the proxy wget resolved for the request, and our proxy checker reports the exit IP, country, latency and anonymity grade in one paste.
Where to go from here
wget's proxy story is environment variables plus the use_proxy switch, and most trouble is one of those two being wrong. Once they are second nature, the discipline is the same as any download tool pointed at real proxies: verify each exit, and pull from a pool that is alive.
The cURL guide is the sibling reference and covers the same checks with more control over headers, how to use proxychains is the route to SOCKS for wget and any other tool, and proxies for web scraping covers picking the right proxy type once a script grows past a one-off download. When a loop of free proxies becomes a chore, a rotating gateway that returns a fresh residential IP per request at $0.44/GB removes the list management for good.