Short answer
SNI (Server Name Indication) is a TLS extension where the client states, already in the Client Hello, which domain it wants to reach. It lets one server with one IP address pick the right certificate among many — essential because the server must send the certificate before it sees any HTTP (where the Host header would otherwise reveal the domain). Without SNI the client gets the server's default certificate, which often does not match, and the handshake fails.
The problem SNI solves
The TLS handshake happens before HTTP. When the server needs to send its certificate, it has not yet seen the HTTP request — and therefore not the Host header that says which domain the user wants. On a server with one domain per IP this is no problem. But in a world where IPv4 addresses are scarce, hundreds of sites typically share the same IP. SNI solves this by moving the domain name all the way forward to the Client Hello, where it is available before the certificate has to be chosen. The whole sequence is shown in the TLS handshake explained.
How it works in practice
The client sets the server_name field in its Client Hello. The server reads it, looks up which virtual host it matches, and sends the corresponding certificate. You can see the field in a handshake:
openssl s_client -connect example.com:443 -servername example.com # without -servername no SNI is sent — the server returns its default certificate openssl s_client -connect example.com:443
Try both against a server hosting several domains: with -servername you get the right certificate, without it you get the default certificate — often for an entirely different domain.
What happens without SNI?
If the client sends no SNI, the server guesses — typically by returning the first or default certificate. That leads to a hostname mismatch if it does not match the domain the user requested. Two common reasons for missing SNI:
- Very old clients (e.g. Windows XP's IE, Java before 7) do not support SNI at all.
- API libraries and scripts that connect to an IP directly, or that do not set the server name correctly.
SNI in nginx: multiple certificates on one IP
Each server block with its own server_name and certificate acts as a virtual host. nginx picks the right one based on SNI:
server {
listen 443 ssl;
server_name a.example.com;
ssl_certificate /etc/ssl/a/fullchain.pem;
ssl_certificate_key /etc/ssl/a/privkey.pem;
}
server {
listen 443 ssl;
server_name b.example.com;
ssl_certificate /etc/ssl/b/fullchain.pem;
ssl_certificate_key /etc/ssl/b/privkey.pem;
}
Both listen on the same IP and port; SNI decides which certificate is served. The server block listed first (or marked default_server) is used when the client sends no SNI.
The privacy gap: SNI is sent in clear text
Because SNI is sent in the Client Hello — before encryption is established — an eavesdropper can see which domain you connect to, even on an HTTPS connection. This is a known privacy problem. The solution is Encrypted Client Hello (ECH), which encrypts the entire Client Hello including SNI. ECH is being rolled out in modern browsers and CDNs but is not yet universal. As we explain in HTTPS explained, the domain itself therefore still leaks in most connections today.
How CertControl uses SNI
When CertControl scans an endpoint, it sends the correct SNI for the domain it is testing — exactly like a real browser — so it gets the right certificate validated and not the server's default certificate. It also flags endpoints where the certificate name does not match the domain being served, which is often caused by an SNI or virtual-host misconfiguration.
Frequently asked questions
Why is SNI necessary?
Because the server must choose and send its certificate during the TLS handshake, before it sees the HTTP request's Host header. SNI moves the domain name forward to the Client Hello, so the server can pick the right certificate among several on the same IP.
What happens if the client does not send SNI?
The server returns its default certificate, which often does not match the requested domain. The result is typically a hostname mismatch or a handshake failure. That is why -servername matters when you test with openssl.
Does SNI encrypt which domain I am visiting?
No, not in standard TLS. SNI is sent in clear text in the Client Hello, so an eavesdropper can see the domain. Encrypted Client Hello (ECH) solves this by encrypting the whole Client Hello, but it is not yet universally deployed.
Can I have multiple certificates on one IP without SNI?
In practice no, not for named domains. Before SNI each HTTPS certificate required its own IP. SNI is precisely what makes virtual hosting with separate certificates on a shared IP possible.
What is Encrypted Client Hello (ECH)?
A newer TLS mechanism that encrypts the entire Client Hello, including SNI, so the domain no longer leaks to eavesdroppers. It is being gradually rolled out in browsers and CDNs, but requires support in both client and server.