Introduction
For three decades the web has lived a contradiction. We encrypted the payload, encrypted the headers, encrypted the cookies. And then, right at the start of every single TLS handshake, the browser politely announced in plaintext exactly which website it was about to visit. Anyone on the wire could read it. Your ISP, the airport Wi-Fi, the captive portal, the corporate proxy, the random middlebox, the nation-state observer. All of them.
That field is called the Server Name Indication, or SNI, and until recently it was the last big leak in TLS 1.3. Encrypted Client Hello, also known as ECH, finally closes it.
This is a practical guide. We will walk through what ECH actually is, why ESNI failed before it, how the new design splits the handshake into outer and inner halves, where the keys live (spoiler, in DNS), and how to enable ECH in the browsers and servers that matter. By the end you will know whether your own connection is ECH-protected or still broadcasting on the open wire.
What Is ECH, in One Paragraph
ECH is a TLS 1.3 extension, standardised as RFC 9849, that encrypts the sensitive parts of the first TLS message the client sends. The Client Hello is the packet that opens every HTTPS connection. Before ECH, that packet included a plaintext SNI field telling the world www.example.com. With ECH, the real Client Hello is wrapped inside a second, encrypted Client Hello. The outer wrapper carries only a generic cover domain. The inner message, the one with the real name, is sealed.
If you have only ever asked "what is ECH" or "what is encrypted client hello", here is the headline. ECH is HTTPS finally encrypting the one thing HTTPS always forgot to encrypt.
TLS Client Hello: the Three-Decade Leak
To understand why ECH matters, you need to understand the TLS Client Hello. When your browser opens a connection to https://example.com, it sends a Client Hello message containing:
- Supported TLS versions
- A list of cipher suites
- Extensions, including ALPN, supported groups, key share, and SNI
- A random nonce
Almost all of that is harmless. The one field that has caused two decades of privacy headaches is SNI. SNI exists because modern hosting puts thousands of distinct websites behind a single IP address. The server cannot know which TLS certificate to present until the client says, in the very first packet, which hostname it wants.
That hostname is sent before any encryption is negotiated. There is no other way to bootstrap the handshake. So for thirty years, SNI encryption was a "future work" comment in the spec, and SNI itself was the giant blinking sign on the wire saying "this person is visiting bank.example, pharmacy.example, dissident-news.example".
The TLS 1.3 rollout closed most of the other leaks. The certificate chain became encrypted. Application data became encrypted. The server-supplied parameters became encrypted. But the Client Hello, the very first message of the handshake, stayed open. TLS 1.3 privacy without ECH was, in practice, partial privacy.
ESNI vs ECH: A Brief History of Failure
The first attempt at fixing SNI was Encrypted SNI, abbreviated ESNI. TLS 1.3 encrypted SNI was a draft standard around 2018, championed by Cloudflare, Mozilla, and Fastly. The idea was simple. Encrypt only the SNI field, leave the rest of the Client Hello plain.
Sounds clean. It was not. ESNI vs ECH is essentially the story of why "encrypt one field" is never enough in modern TLS:
- Encrypting only SNI still leaked enough handshake metadata to fingerprint the destination via the rest of the packet, especially the ALPN list and the key share.
- Middleboxes and censorship engines learned to detect the ESNI extension and selectively drop connections that used it, which was worse than the leak itself.
- The design did not survive contact with future TLS extensions that would also need protection.
Mozilla shipped ESNI experimentally in Firefox 63. By Firefox 85 they were tearing it back out and replacing it with the early ECH draft. Cloudflare deactivated production ESNI in 2021. The standard moved from ESNI to TLS 1.3 ECH, a redesign that encrypted not just the SNI but the entire inner Client Hello. RFC 9849 made that redesign official on 3 March 2026.
How ECH Works: Outer Hello, Inner Hello
The core trick of ECH is structural. The Client Hello is duplicated, and the two copies are layered.
- ClientHelloOuter, sent in the clear. It carries a generic public-name SNI (the cover domain), placeholder cipher choices, and a special
encrypted_client_helloextension that contains the real Client Hello, encrypted with a key the client obtained from DNS. - ClientHelloInner, encrypted inside that extension. It contains the real SNI, the real ALPN, the real cipher list. The server peels it open after seeing the outer.
Any observer on the path sees only the outer. The cover domain looks the same for every site hosted on that CDN. The inner is opaque ciphertext, indistinguishable from any other Client Hello.
Side-by-side comparison
| Field | Plain TLS 1.3 | TLS 1.3 with ECH |
|---|---|---|
| SNI value on wire | Real hostname, plaintext | Cover domain (e.g. cloudflare-ech.com) |
| Cipher list visibility | Visible in outer hello | Generic placeholder outside, real list inside |
| ALPN protocols | Visible | Encrypted |
| Key transport | None needed | ECHConfigList fetched via HTTPS DNS record |
| Fallback if server rejects | N/A | retry-config, then plain TLS |
The outcome on the wire is what cryptographers call "collapsed entropy". To a passive observer, every user on the same CDN looks indistinguishable. Hostname analytics collapse from millions of distinct names to one cover.
The HTTPS DNS Record: Where the Key Lives
For the client to encrypt the inner Client Hello, it needs the server's public ECH key in advance. That key cannot be retrieved over TLS, because the whole point of ECH is that the TLS connection has not started yet. So the key has to live somewhere else. That somewhere is DNS.
Specifically, the HTTPS DNS record, formally known as the HTTPS resource record (RR type 65), defined in RFC 9460. When you look up example.com, alongside the usual A and AAAA records, you can also retrieve a small structured blob that contains:
- ALPN hints (so the client knows to attempt HTTP/3)
- IPv4 and IPv6 hints
- The
ech=parameter, which contains theECHConfigList
Two consequences fall out of this design.
First, ECH inherits the trust model of DNS. If your DNS resolution is being tampered with, an attacker can downgrade you by stripping the ech= parameter, and your browser will fall back to a plain hello. To be safe, you need encrypted DNS in the path. That is why mainstream ECH deployments effectively require DoH, DoT, or DoQ. See our DNS Encryption guide for the practical setup of that lower layer. You can also inspect the ECHConfigList on any domain directly, or pull the raw HTTPS record with our DNS Lookup tool to confirm whether a site has published its ECH key.
Second, ECH and HTTP/3 share the same plumbing. Both rely on the HTTPS RR. The browsers that have deployed ECH did most of the heavy lifting when they shipped HTTPS RR support for HTTP/3 negotiation. ECH is a feature on top of work that was already done.
Browser and Server Reality
This is where most write-ups go stale within a quarter. The honest snapshot of who supports what:
| Vendor | ECH status | Notes |
|---|---|---|
| Firefox 119+ | On by default | Requires DoH active. Since Firefox 129 it also works via the OS DNS resolver where supported |
| Chrome / Chromium | Default for users with secure DNS | Graduated from a flag to default. Recent builds may no longer expose chrome://flags/#encrypted-client-hello. ECH is on automatically when DoH is active and the site publishes a key |
| Edge (Chromium) | Default, plus enterprise policy controls | Same behaviour as Chrome, with extra group-policy switches for managed deployments |
| Brave | Default, with strict DoH out of the box | Chromium base, but the DNS posture underneath is already what ECH needs |
| Safari (macOS / iOS) | Limited public surface | Apple has shipped ECH plumbing in recent releases but exposes no end-user toggle |
| Cloudflare | Default on for proxied hosts | Free tier included. ECH Cloudflare has been in production since the early production rollout |
| NGINX | Available, needs OpenSSL 3.5+ with ECH | NGINX encrypted client hello support landed alongside the OpenSSL release that brought ECH into the mainline library |
| OpenSSL | ECH in 3.5 / 3.6 | Merged into mainline, the moment the library people had been waiting for |
The pattern is what you would expect. Browsers that already had a privacy story (Firefox, Brave) shipped ECH on by default first. Chromium catches up, then graduates the feature from a flag to default. Safari, as usual, says nothing in public. CDNs that wanted ECH for their own metadata cleanup (Cloudflare in particular) deployed first and have the largest server-side footprint.
How to Enable ECH
If you are reading this and want secure SNI today, here is what to actually click. Browsers move fast, so if a setting has been renamed or the flag has graduated by the time you read this, treat the steps as a starting point and search the relevant settings page for "ECH".
ECH Firefox
Newer Firefox builds already have ECH Firefox support enabled by default. The only thing you have to do is make sure DoH is on, because no DoH means no HTTPS DNS record means no key.
- Open
about:preferences#privacy. - Scroll to DNS over HTTPS.
- Set it to Increased Protection or Max Protection, with a provider that supports HTTPS RRs (Cloudflare and NextDNS both do).
To explicitly verify or override:
- Open
about:configin a new tab and accept the warning. - Search for
network.dns.echconfig.enabled. The expected value istrue. - Search for
network.dns.http3_echconfig.enabled. Same,true. - Optional, set
security.tls.ech.grease_http3totrueif you want ECH GREASE on HTTP/3 even when the server has not advertised support.
Enable ECH Chrome
ECH support in Chromium has been graduating from an experimental flag to default behaviour, so the setup depends on your build.
- Make sure secure DNS is on. Open
chrome://settings/security, scroll to Use Secure DNS, and select a provider (Cloudflare, Google, Quad9, or your own). Without DoH, ECH cannot work. - Open
chrome://flagsand search for ECH. If you see an Encrypted Client Hello flag, set it to Enabled. If you do not see one, the feature has already graduated to default for your build and there is nothing to flip. - While you are in the flags page, search for DNS HTTPS SVCB. If a
use-dns-https-svcb-alpnstyle flag is present, set it to Enabled as well. On newer builds this is also already default. - Restart Chrome.
The same logic applies to Edge at edge://flags. ECH Chrome behaviour and Edge behaviour are otherwise identical because both share the Chromium TLS stack. ECH Chrome rollout has been gradual, so the absence of a flag is a feature, not a bug. It means the experiment is done.
Brave
Brave follows the same path as Chrome at brave://flags. Brave also keeps strict DoH on by default, which is exactly what ECH needs underneath. If you flipped DoH off at some point, turn it back on at brave://settings/security.
Safari
Apple has shipped ECH plumbing inside recent Safari releases but exposes no end-user switch. There is no menu, no setting, no flag. ECH is used opportunistically when iOS and macOS DNS code paths can fetch a usable HTTPS record. The honest advice for Safari users who want guaranteed ECH coverage today is to use Firefox or Brave alongside Safari for sensitive sessions.
Server Side: ECH for Operators
If you run your own infrastructure and want ECH on the inbound side, the cleanest path today is OpenSSL 3.5 or 3.6 combined with NGINX. The basic shape:
- Build or install OpenSSL with ECH support enabled.
- Generate an ECH key pair and an
ECHConfig. - Configure NGINX with the new
ssl_ech_certificateandssl_ech_keydirectives. - Publish the
ECHConfigListas theech=parameter inside the HTTPS DNS record for your hostname.
For most operators the realistic shortcut is "put Cloudflare in front of it and click the toggle". Cloudflare's free plan has shipped ECH automatically for proxied origins since the early days. Letting the CDN deal with key rotation, retry-config refresh, and HTTPS RR publishing is genuinely less work than rolling your own. Self-host ECH if you have a reason to. Most people do not.
ECH Test: How to Verify
You enabled the flags. Did anything change? An ECH test answers in minutes, and you can do most of it without leaving our site.
The most useful checks, in order:
- Check the target site for an
ech=blob. The fastest path is our ECH Checker, which fetches the HTTPS RR, decodes the ECHConfigList, and surfaces the HPKE key, cipher suites, and cover public_name in one report. For the raw record without the parse step, our DNS Lookup tool on theHTTPStype shows the sameech=parameter. If there is noech=at all, no client in the world can use ECH on that domain. - Confirm encrypted DNS is in your path. ECH cannot reach the key over plain UDP/53 in any meaningful sense. Verify your DoH is active in browser settings, and double-check there is no captive portal or corporate proxy quietly downgrading you.
- Inspect the handshake from your browser's own DevTools. In Chromium-based browsers, open DevTools, switch to the Security panel, and click any HTTPS request. A connection that used ECH will report it explicitly in the connection details. Firefox shows a similar trail under Network → request details → Security.
- Watch for fallback events. When ECH fails, your browser quietly retries with a normal handshake. If your logs or DevTools show consistent retries, something on the path is stripping the extension. Corporate networks and aggressive captive portals are the usual culprits.
What ECH Does Not Fix
This is the section that should kill any "ECH solves privacy" headlines you might be tempted to write.
ECH protects the SNI, the ALPN, and the rest of the inner Client Hello. It does not protect:
- Your IP address. The server still sees who you are at the network layer. So does your ISP, the routers on the way, the CDN, and anyone who can subpoena them. ECH is not a VPN. If your goal is to hide your origin IP, look at WebRTC Leaks and IP Reputation for the real attack surface.
- Traffic volume and timing. A passive observer can still measure how many bytes you sent and when. Traffic analysis attacks predate ECH by twenty years and are unaffected by it.
- TLS fingerprinting. The cover Client Hello still has a TLS fingerprint. A weak or unique one will mark your client just as cleanly as it did before. JA4 is independent of ECH. We covered this in detail in TLS Fingerprinting JA3 / JA4.
- DNS leaks. If you are still using plain UDP/53, your resolver sees every name you visit, ECH or not. Encrypted DNS is a prerequisite, not a bonus.
- Browser fingerprinting at the application layer. Canvas, audio, fonts, WebGL, Client Hints. None of those go through the TLS layer at all. See Device Integrity for the catalogue of leaks that ECH cannot touch.
ECH is one essential piece of a privacy stack. It is not the whole stack.
FAQ
Q: What is encrypted client hello, in plain English?
A: It is the change that finally encrypts the part of HTTPS that names the website you are visiting. Before ECH, even with HTTPS, anyone watching the wire could see "this person is loading example.com". After ECH, all they see is a generic cover name shared by everyone on the same CDN.
Q: Do I have to do anything to use ECH?
A: In Firefox and Brave, mostly no. They turn it on by default as long as encrypted DNS is also on. In Chrome and Edge it has been graduating from a flag to default, so depending on your build there may or may not be anything to flip. Safari handles it silently. None of this works for sites that have not published an HTTPS RR with an ech= blob.
Q: Does ECH hide my browsing from my employer or school network?
A: Partially. The destination hostname is hidden. The destination IP and the traffic shape are not. If your employer cares enough, they will see that you connected to a Cloudflare IP for forty minutes and downloaded twelve megabytes. They will not see which Cloudflare-hosted site you used. Network operators who require visibility usually respond by blocking ECH outright at the firewall.
Q: How is ECH different from a VPN?
A: A VPN hides your IP and pipes all your traffic through a single endpoint. ECH hides only the hostname in the TLS handshake. They solve different problems. They compose well together but neither replaces the other.
Q: Is ECH the same as DoH?
A: No. DoH encrypts DNS queries. ECH encrypts the TLS Client Hello. They are independent layers. ECH effectively requires DoH to work safely, because the key it needs lives in DNS, but they are different mechanisms protecting different data.
Q: Will ECH break captive portals?
A: Sometimes. Captive portals that intercept TLS to inject a login page get confused when the inner SNI is encrypted. Most browsers handle this by retrying without ECH when the cover handshake fails in a specific way. In practice you may see a one-time login glitch on hotel Wi-Fi the first time you visit a portal-protected network.
Q: How do I check if a specific site has ECH?
A: Run an ECH check on the hostname. The tool fetches the HTTPS RR, parses the ECHConfigList, and surfaces the cover public_name plus HPKE parameters. For the raw record without the parse step, use DNS Lookup on the HTTPS type. Sites behind Cloudflare almost always have an ech= blob. Self-hosted sites usually do not yet.
Recommendations
For privacy users
- Use Firefox or Brave for sessions where SNI privacy matters. Turn DoH on. ECH follows.
- Verify your setup periodically. Flags drift, defaults change, and what was on yesterday might not be on after the next major browser update.
- Combine ECH with encrypted DNS, a clean WebRTC posture, and a non-trash IP. ECH alone does not save you.
For site operators
- If you are already behind Cloudflare, ECH is one toggle away. Use it.
- If you self-host, plan for OpenSSL 3.5 or 3.6 with NGINX, and budget time for HTTPS RR publishing through your DNS provider. Not every registrar exposes RR type 65 yet.
- Watch for fallback storms when middleboxes strip your ECH extension. Log the retry-config events.
For network defenders
- Accept that hostname-based visibility on the wire is over for ECH-enabled clients. Either move detection to the endpoint or design around encrypted metadata.
- Behavioural analysis, JA4 fingerprinting, and IP-reputation signals remain effective. ECH does not blunt any of them.
Curious whether your own browser is leaking SNI right now?
Run a Cyber Identity Scan to see which signals your stack is still broadcasting in the clear.
