The difference between socks5 and socks5h is who looks up the hostname. With socks5:// in curl, your computer resolves example.com through your own DNS resolver and sends the proxy an IP address. With socks5h://, curl sends the proxy the name and the proxy resolves it at the exit. The h is for hostname. Chrome has no socks5h://, because its socks5:// already sends the name.
socks5 vs socks5h in curl
The SOCKS5 protocol lets a client name its destination in three ways: an IPv4 address, an IPv6 address, or a domain name for the proxy to resolve. curl picks with the scheme. socks5:// means "resolve here, send an address", and socks5h:// means "send the name". The same split exists one version down: socks4:// resolves locally, because SOCKS4 can only carry an IPv4 address, and socks4a:// is the extension that lets it carry a name.
That is why guides about DNS leaks tell you to use socks5h://. With plain socks5:// in curl, every lookup goes to the resolver your ISP gave you, with your real address on it, before the connection to the proxy even opens. The traffic leaves through the exit while the lookups name the sites from home.
What Chrome does with socks5://
Chromium's own proxy documentation answers it directly: when the scheme is SOCKSv5, name resolution is always done on the proxy side, even though the protocol allows the client to do it. For an HTTP proxy, name resolution is likewise deferred to the proxy. SOCKSv4 is the one Chrome resolves locally.
So --proxy-server=socks5://host:1080 in Chrome is curl's socks5h://. Typing socks5h:// into Chrome does not get you anything extra, and a proxy list copied from a tool that writes socks5h can be read as socks5 without changing what happens. That is what Mosaic's proxy importer does when it meets the word.
Paste one gateway line. Every profile mints its own exitIn Mosaic: Provider minting. One gateway line, a separate exit for every profile. Free holds 3 profiles. Pro is $49 a month for any number.
Mosaic is a desktop app
Email yourself the link and open it on your computer.
How it works: Provider minting
The lookups that never go through the proxy
The page's requests are not the whole browser. The same Chromium documentation warns that other components may issue DNS lookups directly and bypass the proxy, and suggests a host resolver rule that maps every name to nothing, with an exception for the proxy itself. A browser can send every page request through a SOCKS5 exit and still show your ISP's resolver to a DNS leak test, because one background feature asked the system resolver for a name.
The other gap is UDP. Chromium uses SOCKSv5 only for TCP URL requests, and WebRTC wants UDP. Without a policy telling it otherwise, WebRTC can open UDP paths that never touch the proxy, so a site can see an address the proxy was supposed to hide. That is not a DNS problem, but it is the same shape: traffic the proxy setting does not cover.
So for a browser, the question is not socks5 against socks5h. It is which lookups and packets fall outside the proxy, and whether anything stops them.
How Mosaic closes both
By default a Mosaic profile with a proxy does not hand the proxy's address to Chrome at all. The browser talks to a local relay on 127.0.0.1, started for that profile's launch, and the relay speaks SOCKS5 to a SOCKS gateway. It sends the destination as a domain name, address type 3 in the protocol, so the lookup happens at the exit. Its SOCKS4 path sends the name the SOCKS4a way. Why the relay exists, and what it had to stop doing so the gateway saw a browser rather than a script, is in our relay write-up.
Behind the relay, the browser is given --host-resolver-rules that map every name except 127.0.0.1 to ~NOTFOUND. That is Chromium's own suggestion, applied whenever a proxy is attached: any code path that tries to resolve a name itself gets an error instead of a leak. It is a per-profile privacy switch, dnsOverProxy, and it is on by default. One name is mapped before the wildcard, the companion extension's own loopback host, because rules apply in order and the first version of this swallowed the extension's calls.
For WebRTC, a profile with a proxy runs with --webrtc-ip-handling-policy=disable_non_proxied_udp, so WebRTC cannot send UDP around the proxy.
Which resolver the site sees
Sending the name to the exit does not make DNS invisible. The exit resolves it through some resolver, and a leak test reports that resolver. We measured it through a residential session with plain curl and no browser at all: the lookups went out through Google resolvers in Germany and then the Netherlands, while the exit itself was a Verizon address in the United States. The same machine resolving directly showed its real Austrian ISP. The Austrian line proves the lookups went through the proxy. The German and Dutch lines are a property of the exit, and in our runs Whoer took 30 points off for exactly that, a DNS server in a different country from the IP.
No browser setting reaches that, so Mosaic's proxy check reports it instead. Through the exit it loads edns.ip-api.com, which redirects to a one-time subdomain and then names the resolver that looked it up. If that resolver sits in another country from the exit, the check banner turns amber and says another pool is the only fix. If the redirect fails, the fields stay empty rather than reading as a match, because "we did not find out" is not good news. The other things the check reads before a profile opens are listed in how to check a proxy before you use it. The seller at the far end of the relay sees the hostnames either way, and what else it can read is in what your proxy provider can see.






