TLS Encrypted Client Hello: The RFC 9849 Guide for DevOps Engineers

The Server Name Indication (SNI) field has been the last major plaintext leak in TLS connections. Even with TLS 1.3, network observers could see which domain you were connecting to. RFC 9849, published in March 2026, changes that with Encrypted Client Hello (ECH).
Quick Reference
# Check if a domain supports ECH via DNS
dig +short TYPE65 cloudflare.com
# OpenSSL 3.4+ ECH test
openssl s_client -connect example.com:443 -ech
# Verify ECH in browser (Chrome/Firefox)
# Look for "Encrypted Client Hello" in Security tab
What Problem Does ECH Solve?
In a standard TLS handshake, the client sends a ClientHello message containing:
- SNI (Server Name Indication): The domain name in plaintext
- ALPN: Application protocols (HTTP/2, HTTP/3)
- Supported cipher suites and extensions
This metadata leaks to anyone watching the connection. ISPs, corporate firewalls, and nation-state actors can see exactly which websites you visit, even when the actual content is encrypted.
ECH encrypts the entire ClientHello using a public key published in DNS, hiding the SNI and all other sensitive handshake data.
How ECH Works
ECH uses a two-layer ClientHello structure:
- ClientHelloOuter: Contains a generic "cover" SNI (like
cloudflare-ech.com) and the encrypted payload - ClientHelloInner: The real ClientHello with actual SNI, encrypted inside the outer hello
The flow works like this:
Client Server
| |
| ClientHelloOuter |
| (cover SNI + encrypted |
| ClientHelloInner) |
|------------------------------>|
| |
| Decrypt inner hello |
| Route to real server |
| |
| ServerHello + Certificate |
|<------------------------------|
| |
| (encrypted application data) |
|<----------------------------->|
Deployment Topologies
ECH supports two deployment modes:
Shared Mode
The same server handles both the outer and inner connections. This is common for CDN providers hosting multiple domains:
+------------------+
Client -----------> | CDN Edge Server |
| (terminates TLS) |
+------------------+
Split Mode
A client-facing server decrypts the outer hello and proxies to a separate backend:
+----------------+ +----------------+
Client -----------> | Client-Facing | --> | Backend Server |
| (decrypts ECH) | | (real domain) |
+----------------+ +----------------+
Split mode is powerful for privacy-focused deployments where the frontend never sees the plaintext SNI.
ECH Configuration via DNS
ECH public keys are distributed via HTTPS/SVCB DNS records (RFC 9460). Here is what a typical record looks like:
example.com. 300 IN HTTPS 1 . (
alpn="h2,h3"
ech="AEX+DQBBKwAgACAB..."
)
The ech parameter contains the base64-encoded ECH configuration, which includes:
- Public key: For encrypting ClientHelloInner
- Key identifier: To select the right decryption key
- Cipher suite: HPKE algorithms for encryption
- Maximum name length: Padding guidance
Browser and Server Support
Browser Support (as of March 2026)
| Browser | ECH Support |
|---|---|
| Chrome 120+ | Full support |
| Firefox 118+ | Full support |
| Safari 17.4+ | Full support |
| Edge 120+ | Full support |
Server Support
| Server | Status |
|---|---|
| Cloudflare | Production (all plans) |
| nginx | Experimental (requires BoringSSL) |
| HAProxy | Planned for 3.2 |
| Envoy | Available via BoringSSL |
| Caddy | Plugin available |
Enabling ECH on Cloudflare
Cloudflare enables ECH by default for all zones. To verify:
- Enable DNSSEC on your domain
- Check for the HTTPS record:
dig +short TYPE65 yourdomain.com
You should see an ech= parameter in the response.
Nginx ECH Configuration (Experimental)
Nginx with BoringSSL can support ECH. Here is a basic configuration:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.pem;
ssl_certificate_key /etc/ssl/private/example.com.key;
# ECH configuration
ssl_ech on;
ssl_ech_config /etc/ssl/ech/example.com.ech;
}
Generate ECH keys using OpenSSL 3.4+:
openssl ecparam -name X25519 -genkey -out ech_private.pem
openssl pkey -in ech_private.pem -pubout -out ech_public.pem
Testing ECH Connections
Using curl (with ECH support)
# curl 8.5+ with ECH-enabled OpenSSL
curl -v --ech https://crypto.cloudflare.com/cdn-cgi/trace
Using OpenSSL
openssl s_client -connect cloudflare.com:443 -ech -servername cloudflare.com
Browser Developer Tools
In Chrome or Firefox:
- Open Developer Tools (F12)
- Go to Security tab
- Look for "Encrypted Client Hello: Yes"
Monitoring ECH in Production
For SRE teams, monitoring ECH adoption is important:
# Check ECH status in connection logs
grep -c "ECH accepted" /var/log/nginx/access.log
# Monitor ECH rejection rate
awk '/ECH rejected/ {count++} END {print count}' /var/log/nginx/error.log
Key metrics to track:
- ECH acceptance rate: Percentage of connections using ECH
- ECH retry rate: Clients that fall back after ECH failure
- Key rotation events: Track when ECH keys are updated
Security Considerations
ECH is not a silver bullet. Consider these factors:
DNS Security
ECH relies on DNSSEC or DNS-over-HTTPS to prevent tampering with the ECH configuration. Without encrypted DNS, attackers can strip the ECH parameters.
Anonymity Sets
ECH works best when many domains share the same client-facing server. A single domain behind a unique IP provides no privacy benefit.
Key Rotation
ECH private keys should be rotated regularly. RFC 9849 recommends keeping old keys active for a grace period during rotation.
Troubleshooting Common Issues
ECH Not Working
- Check DNS propagation: Ensure HTTPS records are visible
- Verify DNSSEC: ECH often requires DNSSEC validation
- Browser flags: Some browsers need ECH enabled manually
- Middlebox interference: Corporate proxies may strip ECH
Fallback Behavior
When ECH fails, clients should gracefully fall back to standard TLS. Monitor your fallback rate to identify issues:
# Log ECH failures in nginx
log_format ech_log '$remote_addr - $ssl_ech_status - $request';
Migration Checklist
Ready to deploy ECH? Follow this checklist:
- Verify your CDN/server supports ECH
- Enable DNSSEC on your domain
- Publish HTTPS DNS records with ECH config
- Test with curl and browser tools
- Monitor ECH acceptance metrics
- Plan key rotation schedule
- Update firewall rules if needed
The Future of TLS Privacy
ECH is a significant step toward full TLS privacy. Combined with DNS encryption and QUIC, the entire connection metadata can now be protected from network observers.
For SRE teams, the practical impact is:
- Less visibility for debugging: You cannot inspect SNI at the network level
- Firewall changes: SNI-based filtering will not work
- CDN dependency: Self-hosting ECH requires careful key management
The privacy benefits outweigh the operational complexity for most deployments. Start testing ECH today to prepare your infrastructure.
Conclusion
RFC 9849 makes TLS Encrypted Client Hello an official standard. It solves the long-standing SNI privacy leak by encrypting the entire ClientHello. Browser support is universal, and major CDNs already offer ECH.
For DevOps and SRE teams, now is the time to understand ECH, test your infrastructure, and plan for a future where connection metadata is as protected as the content itself.
Building reliable AI-powered infrastructure? Akmatori is an open-source platform that helps SRE teams deploy and manage AI agents for automated incident response, monitoring, and operational tasks.
