# Does Chrome use QUIC through a proxy? No, and why

> With an HTTP, HTTPS or SOCKS5 proxy set, Chrome reaches sites over TCP tunnels, so a page that gets HTTP/3 direct gets HTTP/2 through the proxy.

Source: https://mosaicbrowser.com/blog/chrome-quic-through-a-proxy

## What happens to QUIC when Chrome has a proxy

With an HTTP, HTTPS or SOCKS5 proxy set, Chrome reaches sites over TCP tunnels, so a page that gets HTTP/3 direct gets HTTP/2 through the proxy.

![Direct: h3 versus Proxied: h2, each name in its own tile: One site, two routes, two protocols](https://mosaicbrowser.com/covers/chrome-quic-through-a-proxy.webp)

Chrome does not use QUIC through the kinds of proxy people actually configure. With an HTTP, HTTPS or SOCKS5 proxy set, it reaches every site over TCP: it asks the proxy for a tunnel and speaks HTTP/2 or HTTP/1.1 inside it. So a site that would get HTTP/3 from a direct visit gets HTTP/2 from the same browser behind a proxy, and both the server and the page can see which one it was.

## Why QUIC needs a path the proxy does not give

HTTP/3 runs on QUIC, and QUIC runs on UDP. A direct Chrome learns that a site speaks it from an `Alt-Svc: h3=":443"` header on an earlier TCP response (or from the site's DNS records), remembers that, and races a QUIC connection on the next visit. Both halves need UDP packets from the browser to the site.

An explicit proxy removes that path. Chromium's own proxy notes, `net/docs/proxy.md` in the source tree, describe each scheme. An HTTP proxy carries an `https://` request as a `CONNECT` tunnel, and that tunnel is a TCP connection. An HTTPS proxy is the same with TLS to the proxy, and may use HTTP/2 to the proxy but not QUIC. Chrome's SOCKS5 support only proxies TCP-based requests and cannot relay UDP at all. Name resolution happens on the proxy's side for HTTP and SOCKS5 proxies alike, so the browser never even learns the site's address to send a UDP packet to.

Chromium also has code for proxies that themselves speak QUIC. That is a different thing from what a proxy seller hands you: residential and datacenter gateways are HTTP or SOCKS5 on a TCP port, which is why [the port number in a proxy line often names its protocol](https://mosaicbrowser.com/blog/port-number-names-protocol).

Mosaic is a desktop app

Email yourself the link and open it on your computer.

[How it works: Provider minting](https://mosaicbrowser.com/features/proxy-providers)

## Why people say QUIC bypasses the proxy

Search for this and the first results are network administrators complaining that QUIC goes around their proxy. They are describing a different setup. A transparent or intercepting proxy sits on the network, and the browser does not know it exists, so Chrome happily sends UDP to port 443 and the interceptor never sees it. Their fix is to block UDP 443 at the firewall, after which Chrome falls back to TCP.

With an explicit proxy, the one passed to Chrome as `--proxy-server`, Chrome knows, and web requests do not leave by any other road. We nearly got this wrong ourselves before launch. A profile's HTTPS appeared to skip the proxy on relaunch, the counter on our test proxy read zero, and "QUIC via a cached `alt-svc`" was one of four mechanisms we worked out in detail as the cause. It was none of them. We had reset the counter after the browser started, and a restored tab had already opened its tunnel during startup. Measured from before the browser existed, the host was in the proxy's log on every launch.

## What a site sees: a proxied visit next to a direct one

The difference is real and readable. On a direct visit to a site that offers HTTP/3, the second page load will usually say `h3`. Through a proxy it says `h2`. The server sees it on the connection, and the page can read it itself:

```
performance.getEntriesByType('navigation')[0].nextHopProtocol
// "h3" direct, "h2" through the proxy

```

Does that mark a browser as proxied? Weakly at most. Plenty of real Chrome users never get HTTP/3, because office firewalls and some home routers drop UDP on 443, and Chrome then stays on TCP without saying anything. A site that wanted to know about a proxy has louder things to read, starting with the exit address and whose network it belongs to.

What matters more is that the TCP path carries fingerprints of its own, and they have to be Chrome's. The TLS handshake and the opening HTTP/2 frames are both read before any page exists. Tesseract Chrome, our engine, does not patch Chrome's networking code, and when we compared its HTTP/2 SETTINGS, header order and ALPN against Google Chrome they were the same ([the Akamai HTTP/2 fingerprint, read field by field](https://mosaicbrowser.com/blog/akamai-http2-fingerprint-read-field-by-field), with the probe). Why the handshake hash still changes between connections is in [why Chrome's JA3 changes](https://mosaicbrowser.com/blog/why-chromes-ja3-changes).

## The other UDP: WebRTC

QUIC is not the only UDP a browser sends. WebRTC opens UDP connections for calls and data channels, and the SOCKS5 limit above applies to it too: there is no way through the proxy for it. Left alone, it goes direct and shows the real address.

So a Mosaic profile with a proxy attached starts with `--webrtc-ip-handling-policy=disable_non_proxied_udp` (the `privacy.blockNonProxiedUdp` setting, on by default). WebRTC cannot send UDP around the proxy. We do not claim it routes WebRTC through the proxy, because for UDP there is nothing to route it through. Mosaic also does not pass `--disable-quic`: a profile with no proxy browses from your own connection and uses HTTP/3 exactly as Chrome would there, and a profile behind a proxy is already on TCP. Each [profile minted from a proxy provider](https://mosaicbrowser.com/features/proxy-providers) gets its own session and exit, and that exit decides everything a site learns from the network.

## Questions

### Does Chrome use QUIC through a proxy?

Not through the HTTP, HTTPS and SOCKS5 proxies people normally configure. Chrome sends the request to the proxy over TCP, opens a tunnel to the site, and speaks HTTP/2 or HTTP/1.1 inside it. QUIC needs UDP to the site, and those proxies give it no UDP route.

### Can a website tell that my browser did not use HTTP/3?

Yes. The server sees which protocol the connection used, and a page can read it too, from nextHopProtocol in the Performance API. On its own it is a weak signal, because many office and home networks block UDP on port 443 and Chrome then falls back to TCP by itself.

### Should I turn off QUIC in an anti-detect browser?

Mosaic does not. A profile behind a proxy already uses TCP for web requests, and a profile with no proxy behaves as Chrome does on that network. Turning QUIC off everywhere would make direct profiles differ from ordinary Chrome for no gain.

### Does WebRTC go through a SOCKS5 proxy in Chrome?

Chrome's SOCKS5 support carries TCP only, so WebRTC's UDP has no way through it. In Mosaic, a profile with a proxy runs with a WebRTC policy that stops UDP from going around the proxy instead.

## Related

[The Akamai HTTP/2 fingerprint, read field by field](https://mosaicbrowser.com/blog/akamai-http2-fingerprint-read-field-by-field): The Akamai HTTP/2 fingerprint is four fields: the SETTINGS values, the window update, any priority frames and pseudo-header order, all read before content.

[Why Chrome's JA3 hash changes on every connection](https://mosaicbrowser.com/blog/why-chromes-ja3-changes): Chrome's JA3 changes because Chrome shuffles its TLS extension order on every connection, and JA3 hashes that order. JA4 sorts first and holds still.

[The port number told us whether a proxy was SOCKS5](https://mosaicbrowser.com/blog/port-number-names-protocol): Nothing in host:port:user:pass says HTTP or SOCKS5, and curl assumes HTTP. At CatProxies we asked the port: 11000 answered SOCKS5, 10000 HTTP.

[Provider accounts: one gateway line, one exit per profile](https://mosaicbrowser.com/features/proxy-providers): Paste your proxy seller's gateway line once and Mosaic mints a separate session for every profile, so each one browses from its own exit address.

[Chrome SOCKS5 proxy with username and password](https://mosaicbrowser.com/guides/chrome-socks5-proxy-with-username-and-password): A Chrome SOCKS5 proxy with username and password fails: Chromium has no SOCKS5 sign-in. Use the seller's HTTP port, allowlist your IP, or relay it.

[How to use a different proxy for each Chrome profile](https://mosaicbrowser.com/guides/use-a-different-proxy-for-each-chrome-profile): Chrome has no proxy setting per profile. Use a proxy extension in each profile, or launch Chrome with its own data folder and --proxy-server.

[Two WebRTC flags we used never existed in Chromium](https://mosaicbrowser.com/blog/webrtc-flags-chromium-ignores): Chrome has one WebRTC command line flag for leaks: --webrtc-ip-handling-policy. We also sent two that don't exist, and Chromium accepted both in silence.



## Mosaic, on your own computer

The browser this blog is about: its own Chromium, fingerprints from real machines and a proxy exit per 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.
