Encrypted Client Hello Hides Less Than You Think

ECH finally encrypts the one field HTTPS always leaked — the site name. But your IP, your DNS lookup, and the size of the crowd you hide in decide whether it means anything.

For thirty years, HTTPS kept a secret badly. It encrypted everything you sent and received — your password, your bank balance, the article you were reading — and then, at the very start of every connection, it announced in plaintext exactly which website you were visiting. That announcement is the SNI field, the Server Name Indication, and it rides in the clear inside the first packet of the TLS handshake because the server needs to know which certificate to present before there’s any encryption to hide behind. Every network in the path — your ISP, the coffee shop router, a national firewall — could read it. The padlock promised confidentiality and delivered it for the contents while leaking the single most interesting piece of metadata there is: the destination.

Encrypted Client Hello closes that hole. It became RFC 9849 in March 2026, after roughly seven years as the draft everyone kept calling “the ESNI successor,” and browsers have been shipping it for a while — Firefox default-on since version 119, Chrome since around 122, Safari on recent iOS and macOS. The headline is exactly what you’d want: the site name is finally encrypted. Within weeks of Cloudflare turning ECH on at scale in late 2024, Russia moved to block it. That is the highest compliment a privacy protocol can receive, and it tells you ECH is doing something real.

It also tells you what ECH is for, and where it stops. Because ECH hides less than the marketing implies, and the gap between what it encrypts and what it actually protects is the whole story.

How you encrypt the thing you need before encryption exists

The chicken-and-egg problem is obvious once you state it. You want to encrypt the SNI, but the SNI is how the server knows which key to use, and you can’t encrypt to a key you haven’t selected yet. ESNI, the first attempt, tried to solve it and failed in ways that made it unshippable.

ECH’s answer is to split the handshake in two. There’s an outer ClientHello, sent in the clear, that names a generic “client-facing server” — for Cloudflare, something like cloudflare-ech.com, a name shared by everyone behind that edge. And there’s an inner ClientHello, carrying the real SNI, the ALPN list, and the rest of the sensitive fields, encrypted to a public key that belongs to the client-facing server. The edge decrypts the inner hello, reads the true destination, and hands the connection to the right backend. A network observer sees only the outer name and learns that you’re talking to Cloudflare — which it already knew from the IP address.

The public key comes from DNS. The client fetches it ahead of time from the site’s HTTPS resource record, the same SVCB-family record standardized in RFC 9460, with the ECH configuration tucked into an ech= parameter. The bootstrapping is specified separately, in RFC 9848. So the flow is: look up the HTTPS record, pull the ECH key, encrypt your real ClientHello to it, wrap it in a decoy hello, and send. Elegant. And it quietly moves a load-bearing part of your privacy into DNS, which matters enormously in a minute.

Your privacy is the size of the crowd

Here is the sentence the RFC is blunt about and the press releases skip: ECH does not hide that you connected to a provider. It hides which of the sites behind that provider you reached. RFC 9849 calls the group you disappear into an “anonymity set” — the collection of co-located servers that share the same client-facing server and present the same externally visible TLS behavior. The mechanism, in the spec’s own framing, reveals that a client is connecting to a particular service provider but not which server in the set terminates the connection.

Read that carefully, because it means your privacy is not a property of ECH. It’s a property of the crowd. Behind Cloudflare’s edge sit tens of millions of sites, so “you’re talking to Cloudflare” tells an observer almost nothing — the anonymity set is enormous and your real destination is one needle in a continent of hay. But point ECH at a small host that fronts exactly one interesting website, and the outer name might as well be the inner one. There’s no crowd to hide in. You encrypted the SNI to reveal the same information through the door you left open. ECH gives you a cloak; the anonymity set decides whether the cloak is a tent or a napkin.

This is why ECH is, in practice, a big-provider feature. It works because a handful of CDNs each terminate a staggering fraction of the web, and their scale is what makes the hiding real. If that makes you slightly uneasy about a privacy technology whose effectiveness depends on further centralizing the internet behind three or four companies — good. It should. That tension is baked in.

The three leaks ECH doesn’t touch

Encrypting the SNI closes one channel. Three others stay wide open, and if you don’t close them too, ECH is theater.

Your destination IP. You still have to route packets to somewhere, and that somewhere is an address in the clear on every packet. When the provider is a giant anycast CDN serving countless names from the same IPs, the address is as ambiguous as the outer SNI, and you’re fine. But the moment a site has its own dedicated IP — plenty do — the IP re-identifies the destination that ECH just encrypted. The address is the leak ECH structurally cannot plug, because the network is addresses.

Your DNS lookup. To get the ECH key, you queried DNS for the site’s HTTPS record — using the real name. If that query went out in plaintext, as ordinary DNS does, you announced your destination to the network one step before the handshake where you carefully hid it. ECH over unencrypted DNS is a locked front door next to an open window. This is why Firefox originally refused to attempt ECH unless DNS-over-HTTPS was on; only since Firefox 129 will it fall back to the OS resolver, and that’s a convenience trade, not a privacy win. If you take one operational thing from this piece: ECH without encrypted DNS barely counts.

Traffic analysis. Packet sizes, timings, and the rhythm of a session are not encrypted by anything, and a patient observer can often fingerprint which site you’re on from the shape of the traffic alone. ECH was never meant to address this and doesn’t pretend to. It’s a reminder that “encrypted” and “unobservable” are different words.

The engineering that made it deployable

Two details are worth admiring, because they’re why ECH shipped when ESNI didn’t.

The first is that browsers send ECH even when they’re not using it. Firefox emits a GREASE ECH extension — random, meaningless, indistinguishable from the real thing — on effectively every TLS and QUIC connection, whether or not the site supports ECH. This is the same GREASE trick that keeps TLS extensible, aimed at a different target: if only ECH users sent ECH, sending it would mark you, and a censor could block the marked connections. When everyone sends it, using it costs you nothing and blocking it means blocking everyone. The anonymity set again, one layer down.

The second is retry. ESNI’s fatal flaw was stale keys: DNS caches the ECH config, keys rotate, and a client that shows up with yesterday’s key was simply stuck. ECH fixes this with retry_configs — if the server can’t decrypt your inner hello, it hands back fresh keys over the already-established connection, and the client transparently tries again. The failure mode that made the predecessor unusable became a self-healing round trip. That’s the difference between a clever idea and a deployable one.

What it actually moves

ECH is the last plaintext identifier in the TLS handshake, and closing it is genuinely worth doing. It ends the era where the padlock quietly narrated your browsing to every box on the wire. Turn it on.

But be precise about what it buys. ECH moves the privacy boundary from “which site” to “which provider,” and it only moves it that far when three other things line up: encrypted DNS so the lookup doesn’t leak, a shared IP so the address doesn’t re-identify you, and an anonymity set large enough to be a crowd rather than a lineup. Miss any of them and you’ve encrypted a field while broadcasting its contents through the next hole over. Get all of them and you’ve achieved something narrower than “nobody knows where you go” — you’ve achieved “the network knows you use Cloudflare, and can’t easily tell which of Cloudflare’s millions of sites you meant.” For most threat models that’s a real improvement. It is not invisibility, and the people selling it as invisibility either don’t understand the anonymity set or are counting on you not to.

Continue the conversation

← Back to Blog