When a proxy checker says working and sites don't load, look at what the checker sent. Most send one GET for a plain http:// page and go green if any bytes come back. Almost nothing you browse is plain HTTP now. For an https:// address the browser asks an HTTP proxy for a CONNECT tunnel instead, and plenty of gateways answer the GET and turn the CONNECT down.

We ran into this writing the check Mosaic runs before it opens a profile. It ended up as three questions rather than one: where the proxy exits, whether it tunnels, and whether it stays put. They break separately, and one green tick can't say which of them did.

Why a proxy can pass a check and still load nothing

Through a proxy, plain HTTP is a single line, GET http://example.com/ HTTP/1.1. The proxy fetches the page itself and passes it back, and since it reads the whole request it is free to rewrite it, log it or refuse it.

HTTPS takes another route. The browser sends CONNECT www.example.com:443 HTTP/1.1 and waits. Only after a 200 does it start TLS, inside a socket the proxy now just copies bytes through, so the page itself stays invisible to the proxy. That second request is where gateways differ. One refuses CONNECT outright, another allows it on some ports only, a third answers 4xx because its exit couldn't reach the target. A checker that only ever sent GET goes green for all three. (A proxy that answers HTTP and refuses CONNECT walks through that one case with curl.)

Our check goes the browser's way instead. It asks the proxy for a tunnel to www.cloudflare.com:443, completes a real TLS handshake inside it and requests /cdn-cgi/trace. If a proxy that answered plain HTTP turns the tunnel down, the result quotes the status code back: "The proxy answered plain HTTP but refused CONNECT (403). Profiles behind it will not load HTTPS sites." We spelled it out because "proxy down" sends people hunting for a network fault they don't have. Chrome's grey ERR_TUNNEL_CONNECTION_FAILED page is the same refusal with the proxy's reason dropped.

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.

How it works: Provider minting

Where does it exit?

The address you connect to is the gateway. The address a site sees is the exit, and the two can sit in different countries. A plan called "Germany" is a request to the seller, not a measurement.

We read the exit from outside, with a location lookup made through the proxy, and record the IP, country, city, ISP and timezone it reports. That matters more for a browser profile than for a scraper, because the profile's timezone, languages and geolocation are drawn from that exit. Believe the label instead and you get a browser that says Berlin while its packets leave from somewhere else.

Does it hold still?

The tunnel probe has a second use. Cloudflare's trace reports the address and country it saw, so one check gets two readings of the exit: one over plain HTTP from the lookup, one over TLS from Cloudflare. If they disagree, the endpoint is rotating.

Rotation is a legitimate product and a poor home for an account. One rotating endpoint we measured answered Peru, Brazil and Bahrain in three consecutive requests. A profile behind it claims one timezone and browses from several countries an hour. The check marks that as rotating rather than failed: the proxy works, and it is the wrong kind for that job.

Comparing two readings has its own trap, and we fell into it. A dual-stack residential exit sent the HTTP lookup over IPv4 and the TLS request over IPv6, and plain string comparison called a sticky session a pool three checks in a row. Only two addresses of the same family can show movement. Two IP addresses, one exit has the full case.

One failure from a residential pool is not a verdict

A residential pool hands out a dead exit some of the time. The gateway answers something like 400 Target website error and the next attempt is fine. Going red on the first of those reports a working proxy as broken, which is the same mistake as trusting one run of a third-party detector.

So a transport failure is retried, and the result says how many attempts it took. Where the proxy comes from a provider, the retry asks for a new session rather than repeating the old one. We watched one session answer 504 four times running while fresh sessions on the same gateway answered 200, and three tries on one token is one try with a longer wait.

Some answers are final and are never retried: rejected credentials, a refused CONNECT, a rotating port refusing a -session- token. Retrying a refusal three times turns an instant, readable answer into a forty-second wait for the same sentence.

What else rides along with the check

Two more readings come from the same open connection, and neither can fail the check. One asks which DNS resolver the exit node uses. On one US residential session the exit was Verizon and the resolvers were Google's, in Germany and the Netherlands, which a scanner can read as a mismatch. The other is the exit's reputation, scored only once there is an address, because an exit on a blocklist can lose an account before the fingerprint is even looked at.

A resolver we could not read leaves those fields empty rather than reporting agreement. "We did not find out" and "they agree" are different answers.

A proxy check in Mosaic: exit address, location, latency, tunnel and reputation
One check, several separate answers

The order to test in, by hand or in Mosaic

  1. Fetch an https:// address through the proxy, so the tunnel is part of the test.
  2. Read where it exits, from a lookup made through the proxy.
  3. Check it twice and compare addresses of the same family.
  4. Retry a timeout before you blame the proxy; read a refusal's words.

The curl commands for each step, plus the browser-side leak checks, are in how to check a proxy before you use it. Mosaic's check does the first three in one pass, runs before every launch, and won't open a profile behind a proxy that has not answered and tunnelled. If the proxy comes from a provider account, each profile mints its own session, so a dead exit costs that profile a fresh session instead of a red row.