Why there's a handshake at all
Encrypting data efficiently and agreeing on a secret key with someone you've never talked to before are two different problems, and TLS solves them with two different kinds of cryptography. Asymmetric (public-key) cryptography can establish trust and agree on a secret without that secret ever being sent in the clear, but it's too slow to encrypt an entire response body with. Symmetric cryptography is fast enough for that, but requires both sides to already share a secret key. The handshake's entire job is to use the slow, trust-establishing kind just long enough to agree on a key for the fast kind — after that, the rest of the connection is symmetric encryption.
The four things that happen before your request is sent
- ClientHello — your device announces which TLS versions and cipher suites it supports, and includes the hostname it's trying to reach in plain text (called SNI, Server Name Indication) so the server knows which certificate to present if it's hosting multiple domains.
- ServerHello + certificate — the server picks a cipher suite from your list and sends back its certificate: its public key, the hostname(s) it's valid for, an expiration date, and a signature chain back to a certificate authority.
- Certificate validation — your device checks that chain against its own list of trusted authorities, confirms the hostname matches, and confirms the certificate hasn't expired. Any failure here stops the connection before a single byte of your actual request is sent.
- Key exchange — both sides derive a shared symmetric key without ever transmitting it directly (modern TLS uses Diffie-Hellman for this), and every byte after this point is encrypted with that key.
All of this happens before your app's actual HTTP request goes anywhere — which is why a TLS handshake failure and an HTTP error are different categories of problem. One means the two sides couldn't agree to talk at all; the other means they talked, and something about the conversation went wrong.
Where interception fits into this
An on-device interception tool participates in this exact handshake, twice: once as the "server" your device talks to (presenting its own certificate, which is why that certificate has to already be trusted — see how HTTPS interception actually works), and once as a "client" opening its own separate handshake with the real destination. Two handshakes, two independent symmetric keys, one tool sitting in the middle able to read both because it holds both keys.
What a TLS error actually tells you
The specific error maps to the specific step that failed, which is usually a faster diagnosis than it looks:
- "Certificate not trusted" / untrusted root — step 3 failed because the certificate's signature chain doesn't lead back to an authority your device trusts. If you're using an interception tool, this is almost always an incompletely trusted certificate — see the certificate setup guide below.
- Hostname mismatch — step 3 failed because the certificate is valid, and trusted, but not for the hostname you actually connected to.
- Certificate expired — step 3 failed on the date check specifically, independent of trust or hostname.
- Handshake failure with no specific certificate error — often step 1 or 2, meaning the two sides couldn't agree on a supported TLS version or cipher suite at all.
If you're setting up on-device interception for the first time, Hollowport's certificate setup guide covers the specific trust step that makes step 3 pass.