How does a TLS server serving several broker hostnames from one endpoint choose which certificate to send?
answer
- the name arrives first
- selection is a lookup, not a guess
- no name means default certificate
- host_name in server_name(0)
- one address, many hostnames
basics
~20 sIt reads the host_name the client put in the server_name(0) extension of its ClientHello and selects a configured certificate that names that host. With no extension, or an unknown name, it falls back to a default certificate and the client rejects the name mismatch.
solid answer
~40 sThe client states which host it wants **before** the server commits to a certificate: `server_name(0)` travels in the `ClientHello`, carrying a `host_name`. The server matches that value against its configured certificates and sends a chain whose end-entity certificate names that host, in `Certificate`. This is what lets one address and one port serve many hostnames over TLS at all — without it a server would have to guess, and every certificate would have to name every host it serves. Two cases go wrong. A client that sends no `server_name(0)` gets whatever default the server is configured with, and usually fails on a name mismatch. A client naming a host the server does not serve gets the same treatment, though the specification also permits the server to abort with `unrecognized_name(112)` instead of continuing.
code
pseudocode · 13 lines# from the ClientHello
requested = server_name(0).host_name # may be absent entirely
function choose_certificate(requested, offered_schemes):
if requested is absent:
return default_certificate # likely a name mismatch later
matches = certificates naming requested
if matches is empty:
return default_certificate # or abort unrecognized_name(112)
for each candidate in matches:
if key type of candidate produces a scheme in offered_schemes:
return candidate
return no usable certificatego deeper
Remember that the client states the hostname it wants at the very start of the handshake, and the server uses that to decide which certificate to send back.
Explain that the name arrives in the ClientHello before the server's flight, that selection intersects the name with the signature schemes offered, and what a missing name falls back to.
When the wrong certificate arrives, check what name the client actually put on the wire rather than what the deployment configured — a caller connecting by address puts none there at all.
Weigh per-name selection against one certificate naming many hosts: independent renewal and blast radius on one side, a simpler deployment and a disclosed list of names on the other.
## The name has to arrive before the certificate is chosen TLS authenticates a **name**, so the server cannot pick a certificate until it knows which name is being asked for. That is why `server_name(0)` travels in the very first message of the handshake, the `ClientHello`, carrying a `host_name` value. By the time the server builds its `Certificate` message the name is already known, and selection is a lookup rather than a guess. The consequence is structural: one address, one port, many hostnames, each with its own certificate. Without the extension a server has exactly one choice of certificate per listening socket, and every hostname it serves has to be named inside that single certificate. ## What selection actually consists of Selection is not only about the name. It is the intersection of several constraints the `ClientHello` imposes at once: - **the host name** — narrow the configured certificates to those naming the requested host; - **the signature schemes offered** — discard any whose key type or chain the client cannot verify; - **the accepted authorities, if hinted** — prefer a chain ending where the client says it can anchor; - **what is left** — send it; if nothing is left, the handshake cannot be authenticated. The name filter runs first because it is the one the deployment thinks about, but a certificate can survive the name filter and still be unusable. ## The two failure shapes | The client sends | The server sends | What the client does | |---|---|---| | a `host_name` the server serves | the matching certificate | proceeds normally | | no `server_name(0)` at all | its configured default | rejects it unless the default happens to name the host it wanted | | a `host_name` the server does not serve | its configured default, or an abort | rejects the mismatch, or sees `unrecognized_name(112)` | The second row is the classic one. An older client, or a caller that connects by address rather than by name, omits the extension entirely; the server has no basis to choose and answers with a default that names some other host. The certificate is perfectly valid — it simply does not name what the client asked for. On the third row, the specification gives the server a genuine choice: it may abort with a fatal `unrecognized_name(112)` alert, or it may continue the handshake. Continuing with a default is the far more common behaviour, which is why the symptom usually surfaces as a name mismatch on the client rather than a clean rejection from the server. ## Why this is a protocol question, not a configuration question The mechanism is fixed by the specification: the field, where it travels, and the fact that it arrives before the server's flight. What differs between deployments is only the table being looked up. That is why the diagnosis transfers everywhere — if the wrong certificate arrives, ask what name the client actually put on the wire, not what name was configured. The two are frequently different, and a client connecting by address puts no name there at all. ## What per-name selection does and does not buy - It **does** decouple certificate lifetime per hostname: each name renews on its own schedule and a failure affects one name. - It **does** let a name be added without reissuing anything for the existing names. - It **does not** hide which name was requested — the extension is in the first message, before anything is encrypted, which is the whole motivation for the later work on concealing it. - It **does not** remove the alternative: a single certificate can name several hosts, which removes the selection step entirely at the cost of renewing all of those names together and exposing the full list to anyone who inspects it. - It **does not** decide anything about what the client then checks. The server's job ends at choosing what to send. ## The boundary with the rest of the handshake How the extension is encoded and acknowledged, and how the peers agree on it, is handshake machinery. What matters here is only the consequence: the requested name is an input to certificate selection, and a mismatch between what the client asked for and what the server chose is the most common "the certificate is wrong" report that turns out to involve no faulty certificate at all.
- A caller connects by address and gets a certificate for an unrelated hostname. What happened?It sent no `server_name(0)`, so the server had nothing to select on and answered with its configured default. The default is a valid certificate for some other host, and the client correctly rejects it because none of the names it carries match what the caller asked for. Nothing is wrong with either certificate; the caller simply never stated a name.
- Can one certificate cover all the broker hostnames instead of selecting per name?Yes, and it removes the selection step: a single end-entity certificate can name several hosts, so any of them matches whatever the client asked for. The costs are that every listed name renews on one schedule and a reissue touches all of them at once, and that the full list of names is visible to anyone who inspects the certificate. What names may appear inside it, and how, is certificate structure rather than wire behaviour.
- Is the requested host name visible to an observer of the handshake?Yes. `server_name(0)` is carried in the `ClientHello`, the first message of the connection, before any key material exists — so the name is in plaintext on the wire even though the certificate that answers it may not be. That exposure is exactly what later work on concealing the initial hello set out to address.
saying these in an interview costs you the question
- Thinks the server reads the requested name from the certificate
- Believes a client that sends no name gets a failure, not a default
- Says the requested host name is encrypted in the first message
- Assumes every hostname needs its own address and port
- Treats an unrecognised name as a mandatory fatal abort