SNI (Server Name Indication)

Security

A TLS extension that carries the hostname the client wants inside the plaintext ClientHello, so the server can choose the matching certificate before any data flows. It is what lets one IP address serve many HTTPS sites, and it is a hint, not encryption.

Also known as Server Name Indication, server_name extension, server_name.

9 min read Updated Aug 30, 2026

Full Explanation

Server Name Indication (SNI) is a TLS extension that carries the hostname a client wants to reach. It travels in the ClientHello, the first message of the handshake. It exists because a server must choose and send its certificate before any application data flows. That happens before the server can read an HTTP Host header. Without SNI, a name-based virtual host is invisible to the server. That is why every HTTPS site once needed its own IP address. SNI is not encryption, not authentication and not an access control. It is an unauthenticated name in clear text. The server may use it to pick a certificate. Identity is still established by verifying that certificate. The extension is named server_name. It is defined in section 3 of RFC 6066.

How it works

  • The client names the site. Clients MAY include a server_name extension in the (extended) ClientHello. RFC 6066 says it is RECOMMENDED that they do so whenever they locate a server by a supported name type (RFC 6066 section 3).
  • What the value may hold. The value must be one fully qualified DNS hostname. It is ASCII, with no trailing dot. There is at most one name per name type. Internationalised names travel as A-labels. Comparison is case-insensitive. RFC 6066 is explicit that "Literal IPv4 and IPv6 addresses are not permitted in HostName". So a client dialling a bare IP address sends no SNI at all.
  • The server selects a certificate. In TLS 1.3, the server_name extension guides certificate selection: "As servers MAY require the presence of the server_name extension, clients SHOULD send this extension when the server is identified by name." (RFC 9846 section 4.5.1.2). RFC 9846 is the current TLS 1.3 specification. It obsoletes RFC 8446. RFC 6066 also permits a server to use the name for other aspects of security policy. That is why proxies route and apply policy on SNI as well as choosing a certificate.
  • Unknown name. A server that understood the extension but does not recognise the name SHOULD do one of two things. It can abort with a fatal unrecognized_name(112) alert. Or it can continue the handshake. In practice, continuing means presenting a default certificate. A warning-level alert is NOT RECOMMENDED, because client behaviour on warnings is unpredictable (RFC 6066 section 3).
  • Missing name. Servers MAY require a valid server_name. A server that requires it SHOULD respond to a ClientHello lacking one by terminating the connection. It sends a missing_extension alert. TLS 1.3 also lists SNI among the extensions a compliant implementation must implement (RFC 9846 section 9.2).
  • Resumption. In TLS 1.3, "the SNI value is always explicitly specified in the resumption handshake, and there is no need for the server to associate an SNI value with the ticket" (RFC 9846 section 4.3.11). Clients SHOULD still store the name with the pre-shared key. The older TLS 1.2 rule was the reverse. A server implementing the extension MUST NOT resume a session when the server_name differs. It does a full handshake instead (RFC 6066 section 3).
  • Asking is not proving. If the certificate the server chooses does not cover the name the client asked for, "this mismatch will become apparent when the client application performs the server endpoint identification" (RFC 6066 section 3). The hostname check fails even though the handshake itself completed.

Why it matters for a CDN

A CDN terminates TLS for very large numbers of customer domains. It uses a small pool of shared, usually anycast, edge addresses. So the destination IP identifies the CDN, not the customer. SNI is the only field in the plaintext handshake that names the site. That makes it the key the edge selects on. The chain works like this. The customer points its hostname at the CDN with a CNAME. DNS returns a shared edge address. The client puts the customer hostname in SNI. The edge server uses that name to choose the certificate. It commonly also chooses the routing, the origin and the security policy for the right zone. Get the name wrong and nothing degrades gracefully. The connection fails before one byte of HTTP is exchanged.

What CDNs do

  • AWS CloudFront lists SNI as the recommended way to serve HTTPS for alternate domain names: "When CloudFront receives the TLS client hello, it uses the domain name in the SNI extension to find the matching CloudFront distribution and sends back the associated TLS certificate." If it cannot immediately determine which domain a request is for, it drops the connection. AWS states that SNI is supported by browsers and clients released after 2010. For older viewers, AWS documents two alternatives. One is a dedicated IP address in each edge location, which carries an additional monthly charge. The other is using the default CloudFront certificate together with the distribution's own cloudfront.net domain name instead of a custom one (CloudFront: choose how CloudFront serves HTTPS requests).
  • Cloudflare offers Encrypted Client Hello (ECH) to mask SNI. It is "enabled by default on Free zones", and other plans can turn it on or off on the Edge Certificates page. Cloudflare says, "We chose cloudflare-ech.com as the SNI that all websites will share on Cloudflare." So an intermediary sees a handshake for that one name. It can tell you are on Cloudflare, but not which site you asked for. The same page documents how a network can deliberately defeat ECH. It can strip ECH configurations from HTTPS DNS records. Or it can answer the use-application-dns.net canary with NXDOMAIN. This is worth knowing before you assume ECH is in force for all your users (Cloudflare: ECH protocol).

Watch out for

  • The name is public. "The plaintext Server Name Indication (SNI) extension in ClientHello messages, which leaks the target domain for a given connection, is perhaps the most sensitive information left unencrypted in TLS 1.3" (RFC 9849 section 1). ECH is standardised in RFC 9849. It splits the ClientHello into an encrypted inner part and a plaintext outer part. This protects the SNI and other sensitive fields, such as the ALPN list. The outer ClientHello SHOULD carry the ECH configuration's public name. The client must offer TLS 1.3 or above.
  • ECH is not a cloak. "ECH is not in itself sufficient to protect the identity of the server. The target domain may also be visible through other channels, such as plaintext client DNS queries or visible server IP addresses" (RFC 9849 section 1). That is why DNS over HTTPS belongs alongside it. What ECH buys is an anonymity set. An observer learns that a client reached a particular provider. It does not learn which server behind it terminated the connection. In split mode, the provider that decrypts the outer handshake is not the origin. It relays the connection to a backend server that terminates TLS (RFC 9849 section 3.1).
  • ECH failure is loud, not silent. When a server rejects ECH, the handshake continues with the plaintext server_name. The client MUST then verify the certificate is valid for the ECH configuration's public name. It MUST abort with an ech_required alert before sending application data. It SHOULD retry on a new connection, using the retry configurations the server supplied (RFC 9849 sections 6.1.6 and 6.1.7). Stale ECH keys in DNS therefore cost a whole extra connection. They fail hard if the public name cannot be authenticated.
  • Clients that send nothing. A ClientHello without SNI gets whatever default certificate the server happens to choose. That is normally the wrong one. This is exactly what openssl s_client shows when you omit -servername. The same applies to connections made to a literal IP address, because SNI cannot carry one. If the server requires SNI, those clients get a missing_extension alert instead of a certificate.
  • The certificate must really cover the name. RFC 9525 obsoletes RFC 6125. Under RFC 9525, "The Common Name RDN MUST NOT be used to identify a service" (RFC 9525 section 2). The name is matched against subjectAltName entries instead. A wildcard is legal only as the complete content of the left-most label. It matches exactly one label. So *.example.com covers www.example.com, but neither example.com nor a.b.example.com (RFC 9525 section 6.3). On a shared edge, this is the usual cause of a wrong-certificate report.
  • SNI and Host must agree. SNI and the Host header sit at different layers. TLS does not force them to match, but HTTP does. A request for an https resource MUST be rejected unless it arrived over a connection secured by a certificate valid for that target URI's origin. A server that considers a request misdirected answers 421 (RFC 9110 section 7.4). RFC 6066 pushes the same way. Once server_name is established in the handshake, the client SHOULD NOT request a different server name at the application layer.

Best practice

  • Always send SNI. Send the same hostname you will put in the Host header. Verify what came back rather than assuming. openssl s_client -servername NAME -connect HOST:443 prints the certificate the server actually chose for that name.
  • On a shared address, ensure every certificate's subjectAltName list covers the exact SNI values in use. Remember the one-label wildcard rule. Keep a deliberate default certificate for clients that send no name. Expect their hostname check to fail.
  • Decide explicitly what a server should do with an unknown name. A fatal unrecognized_name alert makes misconfiguration obvious. Continuing with a default certificate instead turns it into a confusing client-side certificate error.
  • When a CDN terminates TLS for you, confirm which name it keys on. It is the customer hostname in SNI, not the origin hostname. Prefer SNI-only termination unless you have measured demand from pre-2010 clients, because dedicated IPs are a chargeable extra on CloudFront.
  • To close the plaintext leak, turn on ECH and encrypted DNS together. ECH alone leaves DNS lookups and server IP addresses visible. Publish and rotate ECH configurations carefully. A stale key costs a rejected handshake plus a retry per client.
  • Never treat SNI as a security boundary. It is attacker-controlled, unauthenticated input. Use it to select a certificate and to route. Let certificate verification establish who the server is.

Examples

# See SNI in action with openssl
$ openssl s_client -servername www.example.com -connect cdn.example.com:443 2>&1 | grep 'subject'
subject=CN = www.example.com

# Without SNI, you might get the wrong cert
$ openssl s_client -connect cdn.example.com:443 2>&1 | grep 'subject'
subject=CN = default.cdn.example.com  # Default/fallback cert

# Check if Encrypted Client Hello (ECH) is supported
$ dig TYPE65 example.com  # HTTPS record contains ECH config

# Nginx: SNI-based virtual hosts
server {
    server_name site1.example.com;
    ssl_certificate /etc/ssl/site1.pem;
}
server {
    server_name site2.example.com;
    ssl_certificate /etc/ssl/site2.pem;
}

Frequently Asked Questions

A TLS extension that carries the hostname the client wants inside the plaintext ClientHello, so the server can choose the matching certificate before any data flows. It is what lets one IP address serve many HTTPS sites, and it is a hint, not encryption.

# See SNI in action with openssl
$ openssl s_client -servername www.example.com -connect cdn.example.com:443 2>&1 | grep 'subject'
subject=CN = www.example.com

# Without SNI, you might get the wrong cert
$ openssl s_client -connect cdn.example.com:443 2>&1 | grep 'subject'
subject=CN = default.cdn.example.com  # Default/fallback cert

# Check if Encrypted Client Hello (ECH) is supported
$ dig TYPE65 example.com  # HTTPS record contains ECH config

# Nginx: SNI-based virtual hosts
server {
    server_name site1.example.com;
    ssl_certificate /etc/ssl/site1.pem;
}
server {
    server_name site2.example.com;
    ssl_certificate /etc/ssl/site2.pem;
}

Yes. SNI (Server Name Indication) is also known as Server Name Indication, server_name extension, server_name. A TLS extension that carries the hostname the client wants inside the plaintext ClientHello, so the server can choose the matching certificate before any data flows. It is what lets one IP address serve many HTTPS sites, and it is a hint, not encryption.

Related CDN concepts include: