What is SNI? Server Name Indication in TLS
SNI (Server Name Indication) is the field in which a client tells a server which hostname it wants, at the very start of a TLS connection. It is part of the SSL and TLS glossary because it explains why many HTTPS sites can share one IP address, and why the wrong certificate sometimes appears.
- Carries
- one DNS hostname in ASCII, without a trailing dot; a literal IPv4 or IPv6 address is not permitted [1]
- Sent in
- the ClientHello, the first message of the handshake, before anything is encrypted
- In TLS 1.3
- every implementation must support it, and a server may refuse a ClientHello without it [2]
The problem SNI solves
A server presents its certificate before any HTTP request arrives. When one address serves many sites, the server has to choose which certificate to present before the browser has said which site it wants, and without more information it cannot choose correctly.
SNI moves the name forward. The client states the hostname in its first message, the server reads it, picks the certificate that covers that name, and the handshake continues. This is what makes it ordinary to host many HTTPS sites on one IP address, each with its own certificate.
The term is often searched as SSL SNI, but it is a TLS extension: RFC 3546 added it to TLS 1.0, RFC 6066 restated it for TLS 1.2, and RFC 8446 lists it for TLS 1.3 [1][2].
Where the name travels
The name is carried in the server_name extension of the ClientHello, the first message of the handshake, defined in RFC 6066 §3. TLS 1.3 makes it mandatory to implement: RFC 8446 §9.2 requires every implementation to support server_name for applications that can use it, and allows a server to end a handshake that arrives without it [2].
Because a certificate has to be chosen before the connection is encrypted, the name travels before encryption too. Someone watching the network can see which site is being requested, though not the pages or data exchanged afterwards. TLS 1.3 encrypts every handshake message after the ServerHello, the server's certificate included [2][3]; the ClientHello is not among them. RFC 9849 calls the plaintext SNI perhaps the most sensitive information left unencrypted in TLS 1.3 [3].
What happens without SNI
If a client sends no name, or something on the path strips it, the server falls back to its default certificate. The browser then receives a certificate for a different name and reports a name mismatch, not anything mentioning SNI, which is why this failure is diagnosed slowly. The browser compares the name it asked for with the subject alternative name list in the certificate, not with the certificate CN.
The same symptom appears when the server has a certificate for the name but the virtual host matching the name is configured wrongly. In both cases the question is the same: which certificate does the server present when asked for this exact hostname. For an app that pins certificates or keys, that certificate also has to match the pin the app carries, or the connection is refused.
SNI on servers and proxies
On a web server, each virtual host or server block declares the names it answers for, and the name in SNI selects the block and its certificate. One block is the default: it answers any name nobody else claimed, and any client that sends no name at all.
Load balancers and CDNs use the same field before they decrypt anything. They can route a connection to the right backend, or hand it through unopened, by reading the name in the ClientHello. That is why an edge that terminates TLS for many customers needs SNI to choose the certificate it presents for each of them.
Wildcard and multi-name certificates do not remove the need for SNI; they reduce how many certificates the server has to choose between. A wildcard for *.example.com still leaves the server choosing between that certificate and every other one it holds. A single certificate covering every hosted name is the only arrangement that works without it.
How to test it
OpenSSL sends a name when you give it one, and can be told not to:
$ openssl s_client -connect example.com:443 -servername www.example.com
$ openssl s_client -connect example.com:443 -noservernameSince OpenSSL 1.1.1, s_client fills in the SNI from the -connect host whenever that host looks like a DNS name, so -servername matters when the hostname you test differs from the host you dial [4]. Point -connect at an IP address and no name is sent unless you add one.
Compare the certificate subject and names in the two outputs. If the first shows the right certificate and the second shows the default certificate, the server relies on SNI, which is normal. If both show the wrong one, the problem is the server's configuration, not the client.
Common SNI failures
Connecting by IP address. SNI carries host names only; RFC 6066 does not allow a literal IP address in it. A client that connects to an address directly sends no name and receives the default certificate.
Old tools and libraries. Scripts and embedded clients that predate SNI, or that set it only when told to, get the default certificate and report a mismatch.
A server that requires a name. A TLS 1.3 server may require server_name, and should then close a connection that lacks it with a missing_extension alert [2]. The client then sees a handshake failure, not a wrong certificate.
A name not configured on the server. The client sends the right name, but no virtual host claims it, so the default block answers with its own certificate.
Different names in SNI and in the Host header. The TLS name and the HTTP name are separate fields. A server can answer 421 Misdirected Request when a request names a host the connection was not set up for (RFC 9110 §15.5.20) [5], so a client that sets them independently can fail after a successful handshake.
SNI and privacy
The visible hostname in the ClientHello is a known trade-off of the ordering, not a flaw in an implementation. Hiding it in transit also leaves the site on record elsewhere: certificate transparency logs publicly record TLS server certificates as they are issued (RFC 9162) [6], and Chrome does not validate certificates that lack the log proofs its policy requires [6].
Encrypted Client Hello (ECH)
ECH, published by the IETF as RFC 9849, encrypts the ClientHello itself [3]. The client puts the real hello, with the true SNI, inside an outer ClientHello whose SNI carries the public_name of the client-facing server. It encrypts with a key the site publishes in advance, in an HTTPS or SVCB record in DNS (RFC 9848) or preconfigured [3]. A server that cannot decrypt the inner hello completes the handshake with the outer one; RFC 9849 calls that rejecting ECH.
Earlier iterations of the extension were called ESNI, Encrypted Server Name Indication [7]. Chrome Platform Status lists ECH as enabled by default from Chrome 117, and the Firefox 119 release notes announce ECH as available to Firefox users [7]. ECH applies only to sites that publish an ECH configuration [3].
FAQ
What is SNI?
A TLS extension, defined in RFC 6066, in which the client sends the hostname it wants in its first message, so the server can present the certificate for that name. It lets one IP address serve many HTTPS sites.
Why does my server show the wrong certificate?
Usually because the server did not match the requested name to a virtual host and presented its default certificate, or because the client sent no name. Test with openssl s_client and -servername set to the exact hostname.
What is the difference between SNI and SAN?
SNI is the name the client asks for; the subject alternative name (SAN) list is the set of names a certificate covers. The server picks a certificate by SNI, and the client checks its name against the SAN list.
Is SNI encrypted?
Not in ordinary TLS, TLS 1.3 included: the name travels before encryption begins, in view of the network. Encrypted Client Hello (ECH) encrypts it where both sides support it.
Do all browsers support SNI?
Every TLS 1.3 implementation is required to support it (RFC 8446 §9.2), so any browser that speaks TLS 1.3 does. No name arrives from old libraries and scripts, or from connections made to a bare IP address.
What is ECH?
Encrypted Client Hello, RFC 9849, is the IETF standard that encrypts the ClientHello, hostname included, under a key the server publishes in advance. Observers see only the public name of the server in front.
Related terms
The connection is covered under TLS; certificates that list several names are under SAN certificates, and what any TLS certificate contains is under SSL certificates. The rest of the vocabulary is in this glossary.
Sources
IETF, RFC 6066, Transport Layer Security (TLS) Extensions: Extension Definitions, §3 Server Name Indication; RFC 3546, Transport Layer Security (TLS) Extensions.
IETF, RFC 8446, The Transport Layer Security (TLS) Protocol Version 1.3, §1.2 and §9.2.
IETF, RFC 9849, TLS Encrypted Client Hello; RFC 9848, Bootstrapping TLS Encrypted ClientHello with DNS Service Bindings.
OpenSSL, openssl-s_client manual page, options -servername and -noservername.
IETF, RFC 9110, HTTP Semantics, §15.5.20 421 Misdirected Request.
IETF, RFC 9162, Certificate Transparency Version 2.0; Chrome Certificate Transparency Policy.
Chrome Platform Status, TLS Encrypted Client Hello (ECH); Mozilla, Firefox 119.0 release notes.