You configure a proxy in a German exit, run your collection, and the target keeps serving you content for the wrong region. The exit address checks out as German, the requests succeed, and yet the results look like they came from wherever your server actually lives. A common cause is that the connection went through the proxy but the name resolution did not.
This is a DNS leak. In a privacy context it is described as your resolver seeing which domains you visit, and that is real, but for data collection there is a more immediate consequence: DNS resolution is often geographically aware, so resolving locally while exiting remotely produces a mismatch that can hand you the wrong regional endpoint and quietly poison a geo-targeted dataset.
What actually leaks, and why it matters here
A request to a hostname involves two steps: turning the name into an address, then connecting to that address. A proxy intercepts the second step. Whether it intercepts the first depends entirely on your client.
When the client resolves locally, the DNS query goes out from your own network to your own resolver, revealing the domain to your ISP or resolver operator, and returning an answer computed for your location.
That last part is what breaks collection. Large sites sit behind CDNs and geo-aware DNS that return different addresses depending on where the query came from, so a locally resolved lookup can point at an edge node near your server rather than near your proxy exit. You then connect to that node through a German address, and the mismatch can produce content for the wrong region, inconsistent results between runs, or a signal that looks unusual to the target. If your work depends on city-level targeting, this failure mode is worth ruling out first when geography looks wrong, alongside the geolocation database differences that are the other common cause.
HTTP proxies rarely leak, SOCKS5 often does
The behaviour splits by protocol, and this is the core of the problem.
With an HTTP proxy, an HTTPS request uses CONNECT and sends the hostname to the proxy, which resolves it remotely. Plain HTTP similarly sends an absolute URL containing the hostname. In both cases the proxy performs the lookup by design, so ordinary HTTP proxy usage does not leak DNS.
With SOCKS5, the protocol supports both. It can accept a hostname and resolve remotely, or accept an address that the client resolved itself. Which one happens is a client decision, and many clients default to resolving locally. This is why the same gateway leaks through one configuration and not another, and it is almost always a client-side setting rather than anything to do with the proxy.
In most tooling the distinction is a single character. socks5:// means resolve locally, socks5h:// means hand the hostname to the proxy. The h is the whole fix.
Fixing it by client
curl. Use the socks5h scheme, or --proxy with that scheme, rather than socks5:
# leaks: resolves locally
curl -x socks5://customer-USERNAME-country-de:PASSWORD@p.shifter.io:443 https://example.com
# correct: hostname resolved at the proxy
curl -x socks5h://customer-USERNAME-country-de:PASSWORD@p.shifter.io:443 https://example.com
Python. With requests and PySocks, the scheme carries the same meaning, and it is easy to get wrong because both spellings work:
import requests
user = "customer-USERNAME-country-de"
PROXY = f"socks5h://{user}:PASSWORD@p.shifter.io:443" # note the h
r = requests.get("https://example.com",
proxies={"http": PROXY, "https": PROXY}, timeout=20)
Simplest of all, use the HTTP scheme against the same gateway, which resolves remotely by default and avoids the question entirely. That is the configuration in using residential proxies with Python.
Node. Socks agents typically expose a flag for remote resolution; check that it is enabled rather than assuming, since defaults differ between libraries and versions.
Headless browsers. This is where leaks are most likely, because a browser has its own resolver behaviour independent of the proxy setting. Chromium resolves through its own stack and needs the DNS path constrained explicitly when using SOCKS; Firefox has a preference controlling whether SOCKS hostnames are resolved remotely, and it is not always on by default. If you drive browsers, verify rather than assume, and note the browser-specific leak channels below.
Testing whether you actually leak
Do not assume from configuration. There are three levels of check.
The quickest is to compare what the target sees against what you expect: fetch an endpoint that reports the address it observed and confirm it matches your exit region, then fetch a geo-sensitive page and confirm the content matches. If the address is right but the content is wrong, DNS is a prime suspect.
More directly, watch for outbound DNS traffic while a proxied request runs. On the machine making the request, if you see queries for your target’s hostname leaving on port 53, the resolution is happening locally:
# terminal 1
sudo tcpdump -n -i any port 53
# terminal 2
curl -x socks5h://customer-USERNAME-country-de:PASSWORD@p.shifter.io:443 https://example.com
If queries for the target’s hostname appear in the capture, the client resolved locally and you have found the leak.
Third, for browser automation, use one of the public DNS leak test pages, which report the resolvers that answered on your behalf, and check whether they sit in your exit’s region or yours.
The other leak channels worth knowing
DNS is the common one, but for completeness, three others produce the same class of failure.
IPv6. If the proxy handles IPv4 only and your system prefers IPv6 for a dual-stack target, that traffic can bypass the proxy entirely. Disabling IPv6 on the machine doing the collection, or forcing IPv4 in the client, removes an entire category of confusing results.
WebRTC. In real browsers, WebRTC can expose local and public addresses through a separate mechanism that ignores proxy settings. If you are driving a browser for anything identity-sensitive, disable it.
System and library defaults. Some runtimes cache DNS results aggressively or consult the OS resolver regardless of proxy configuration, and a hosts-file entry or a local caching resolver will override everything you configured.
If identity consistency matters for your work, DNS is one layer among several, and the broader set of signals that need to agree is covered in TLS and HTTP/2 fingerprinting and avoiding blocks.
A quick checklist
Prefer the HTTP scheme against the gateway unless you specifically need SOCKS5, since it resolves remotely by default. If you use SOCKS5, use socks5h everywhere and grep your codebase for bare socks5:// to catch stragglers. Verify with a packet capture on port 53 rather than trusting the configuration. Force IPv4 if your proxy path is IPv4 only. Disable WebRTC in automated browsers. Then re-run a geo-sensitive request and confirm the content matches the exit region rather than your own.
The bottom line
A DNS leak means your traffic went through the proxy while the name resolution did not, which exposes the domains you query to your own resolver and, more importantly for collection, resolves them from your location rather than your exit’s. HTTP proxying resolves remotely by default and rarely leaks; SOCKS5 leaks whenever the client resolves locally, which is why socks5h versus socks5 is the single most common fix. Headless browsers need explicit attention because they resolve independently of your proxy setting. Test with a packet capture instead of trusting configuration, and rule out IPv6 and WebRTC while you are there. When a geo-targeted job returns content for the wrong region and the exit address looks correct, this is the first thing to check.
The gateway speaks both HTTP(S) and SOCKS5 on the same endpoint, so switching schemes to test costs nothing: see gateway and authentication. The product is residential proxies with country and city targeting and per-GB pricing.