Error reference Libraries

How to Fix Python Requests ProxyError

requests.exceptions.ProxyError means the failure happened on the proxy leg of the request, not at the target site: the proxy hostname did not resolve, the port refused the connection, or the proxy rejected your CONNECT tunnel. The wrapped inner message tells you which. This guide decodes each variant and fixes the proxies dict, credential, and environment mistakes behind them.

requests.exceptions.ProxyError

What requests.exceptions.ProxyError Actually Means

requests raises ProxyError — a subclass of ConnectionError — when the proxied path itself cannot be established. The stack is requests wrapping urllib3, so the useful detail lives in the inner message. Three variants cover most cases: "Cannot connect to proxy" with a NameResolutionError or NewConnectionError means the proxy hostname or port is wrong, or the route is blocked; "Connection refused" or "Connection reset" means nothing is listening there or access was denied; and "Tunnel connection failed: 407" (or 403) means the proxy answered your CONNECT and rejected it — an authentication or permission problem, not connectivity.

The scope is the key insight: ProxyError is about the leg between you and the proxy. If the target site were down you would see ConnectTimeout or a plain ConnectionError without proxy wording. So the debugging surface is small and local: the proxy URL, the credentials, the proxies dict, and the environment variables that can silently override all three.

One near-neighbor to rule out: a socks5:// URL without the SOCKS extra installed raises InvalidSchema ("Missing dependencies for SOCKS support"), not ProxyError — same neighborhood, different fix.

requests.exceptions.ProxyError

How to Fix ProxyError, Step by Step

The wrapped inner exception resolves most cases on the first read — start there, then verify configuration layer by layer.

  1. Read the inner message: Tunnel connection failed: 407 is credentials, Cannot connect to proxy is host/port/network, and NameResolutionError is a typo in the proxy hostname.
  2. Verify the proxy URL end to end — scheme, host, port: http://user:pass@host:port. A missing scheme or stray whitespace breaks parsing without an obvious error.
  3. Set both keys in the proxies dict. The keys name the target URL's scheme, not the proxy's — a request to an https:// site never consults an http-only dict.
  4. URL-encode credentials with urllib.parse.quote: a raw @, :, /, or # in the password corrupts the parsed URL and surfaces as auth failures or garbage hostnames.
  5. Replay the identical proxy URL with curl. If curl succeeds and requests fails, the bug is in the Python configuration; if both fail, it is the credentials or the network.
  6. Check the environment: HTTP_PROXY, HTTPS_PROXY, and NO_PROXY are honored by default and can override your code — set session.trust_env = False to isolate.
  7. On a 407, re-copy the username and password from your provider dashboard, and inspect any targeting flags embedded in the username — a typo there fails authentication too.
  8. For SOCKS URLs, install the extra with pip install requests[socks] and prefer socks5h:// so DNS resolves through the proxy rather than locally.
requests.exceptions.ProxyError

Getting the proxies Dict Right for a Real Proxy Network

The proxies dict trips up nearly everyone once: its keys describe the traffic being proxied, not the proxy. In practice both keys point at the same proxy URL — and that URL's scheme is normally http:// even for HTTPS targets, because requests opens a plaintext connection to the proxy, issues CONNECT, and runs end-to-end TLS through the tunnel. Your payloads stay encrypted; only the tunnel setup is plaintext.

Authentication is the other half. With ProxyOmega, the proxy password is your dashboard API key, and targeting rides on the username — -country-us for geo, -session-job42 for a sticky IP held up to 24 hours, -ttl-600 to cap a session's lifetime in seconds. If you would rather keep credentials out of code entirely, whitelist your server's IP in the dashboard and drop the user:pass from the URL.

One proxy URL, two dict keys

Define http and https keys with the same value: http://USERNAME:[email protected]:10000. That single line covers plain and TLS traffic. Since every ProxyOmega port also serves SOCKS5, swapping the scheme to socks5h:// is the only change needed to switch protocols.

Credentials that survive URL parsing

API keys are URL-safe, but if you ever embed passwords with special characters, run them through urllib.parse.quote first. For containers and CI, IP whitelisting removes secrets from code and environment entirely — just remember it needs a stable egress IP, or connection resets replace your 407s.

Sessions, stickiness, and rotation

Use requests.Session for connection pooling, and decide IP behavior on the username. Rotating ports on Budget Unlimited (/plan-unlimited/) give a changing exit for crawl-style traffic; a -session- flag keeps one IP across a login-plus-scrape flow. For per-GB jobs with state, city, or ASN targeting, Platinum (/plan-platinum/) uses the same auth scheme.

requests.exceptions.ProxyError

A Correct requests Setup Through a Proxy

This setup encodes the password defensively, sets both dict keys, ignores conflicting environment variables, and uses split connect/read timeouts — the combination that avoids ProxyError and its neighbors.

import requests
from urllib.parse import quote

username = "USERNAME-country-us-session-job42"
password = quote("YOUR_API_KEY", safe="")

proxy = f"http://{username}:{password}@residential.proxyomega.com:10000"
proxies = {"http": proxy, "https": proxy}

session = requests.Session()
session.trust_env = False  # ignore HTTP_PROXY / NO_PROXY from the environment

r = session.get("https://api.ipify.org", proxies=proxies, timeout=(15, 30))
print(r.status_code, r.text)
FAQ

Frequently asked questions

What does "Tunnel connection failed: 407" mean inside ProxyError?
The proxy is reachable — it answered your CONNECT request — but rejected the credentials, so the tunnel was refused with 407 Proxy Authentication Required. Re-copy the username and password exactly, URL-encode special characters, and verify any targeting flags embedded in the username. If your provider supports IP whitelisting, that removes credentials from the URL entirely.
Why does requests ignore my proxies dict?
The dict keys name the target URL's scheme, not the proxy's. A request to an https:// site only consults the https key — if you set only http, the request goes direct. Environment variables can also interfere: HTTP_PROXY, HTTPS_PROXY, and NO_PROXY are honored by default, so set trust_env = False to isolate your code's config.
Do I need an https:// proxy URL for HTTPS websites?
Usually not. Standard practice is an http:// proxy URL for both dict keys: requests opens a plaintext connection to the proxy, issues CONNECT, and then runs end-to-end TLS to the target through the tunnel. Your traffic stays encrypted. Declaring https:// wraps the proxy hop itself in TLS, which many stacks and plaintext CONNECT ports do not support.
How do I use a SOCKS5 proxy with requests?
Install the extra first — pip install requests[socks] — or you will hit InvalidSchema: "Missing dependencies for SOCKS support". Then use socks5h://user:pass@host:port in both dict keys; the h suffix resolves DNS through the proxy. On ProxyOmega, SOCKS5 runs on the same port as HTTP and HTTPS, so only the scheme changes.

One proxies dict, zero guesswork. Start routing today.

Username plus API key or IP whitelist — with country targeting and sticky sessions riding on the username, on ProxyOmega's 90M+ IP network.

ProxyOmega ProxyOmega

90M+ ethically-sourced IPs across 200+ countries and 30,000+ cities. Residential, mobile, ISP and IPv6 proxies for scraping and AI agents.

GDPRCCPA
Product
Premium Unlimited Budget Unlimited Residential / ISP Mobile IPv6 Chrome Extension
Solutions
Web scraping AI agents Price monitoring SERP & SEO Integrations All use cases
Resources
Glossary Error codes Free tools Proxies by platform Locations
Company
About Blog Docs Reseller program Affiliate Contact Sign in
© 2026 ProxyOmega Ltd. All rights reserved.