HTTPS, TLS, and the headers that protect your visitors

Self-signed, wrong hostname, untrusted: when your TLS cert isn't really trusted

Most people think of a TLS certificate as either working or expired. Expiry is the famous failure, but it's only one of several ways a certificate stops being trusted, and the others throw the same full-screen browser warning that scares users off and tells them, correctly, that the connection can't be verified.

A certificate's job is to prove two things: that the connection is encrypted, and that you're really talking to the site you think you are. The second part is the one that breaks in quiet ways. A cert can be perfectly valid and current and still fail trust, because it was issued by nobody the browser recognizes, or it was issued for a different name, or the server didn't send the full chain that vouches for it.

The three ways trust breaks that aren't expiry

These are distinct problems with distinct causes, and the scanner reports them separately because the fix differs. What they share is the outcome: the browser refuses to trust the connection.

A self-signed certificate is one your server issued to itself, with no recognized authority backing it. It encrypts fine, but it proves nothing, because anyone can sign their own cert claiming to be anyone. Browsers reject it outright. A hostname mismatch is a real, properly-issued certificate that's valid for the wrong name: the cert says www.yoursite.com but the visitor reached yoursite.com, or it's a leftover cert for a different domain on the same server. The cert is genuine; it just doesn't match the door the visitor knocked on, so trust fails. An untrusted or incomplete chain is a cert from a real authority where the server forgot to send the intermediate certificates that link it back to a root the browser trusts. The cert is fine; the server's configuration left out the paperwork that proves it.

encrypted
self-signed
wrong host
broken chain
Your connection is not private
NET::ERR_CERT_DATE_INVALID
Encryption alone isn't trust. Three different cert faults all land the visitor on the same warning.

Why a valid cert still shows a warning

The encryption can be working while the identity check fails, and that's the part that confuses people. "But it's HTTPS, the data is encrypted" is true and beside the point. The warning isn't about whether the bytes are scrambled. It's about whether the browser can prove who scrambled them.

That distinction is the whole reason certificates exist. An attacker doing a machine-in-the-middle can offer the visitor a self-signed cert too, and it'll encrypt the connection just as well, straight to the attacker. The only thing that stops that is the trust chain: a recognized authority vouching that this cert really belongs to this hostname. When your cert is self-signed, the visitor can't tell your server from an attacker's. When it's for the wrong hostname, the proof doesn't apply to the site they're on. When the chain is incomplete, the browser can't follow the vouching back to a root it trusts. In every case the browser does the right thing and warns, because it can't confirm the identity. This is the trust side of TLS, separate from the cert simply expiring, and just as visible to anyone who connects.

The fix, by failure mode

Each of these has a clean cause and a clean fix, and a free, automatically-renewing certificate solves most of them at once.

# self-signed cert generated on the box
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem
# encrypts, but no browser trusts it

# or: cert is for www.yoursite.com, served on yoursite.com
# or: only the leaf cert is sent, intermediates missing
A real CA-issued cert for the exact hostname, with the full chain served. Let's Encrypt automates all three.

For self-signed: replace it with a certificate from a real authority. Let's Encrypt is free and automated, so there's no reason to run self-signed in production. For a hostname mismatch: issue the certificate for every name the site actually answers on, including the apex and www, or set up the redirect so visitors only reach the name the cert covers. For an incomplete chain: configure your server to send the full chain (the leaf plus the intermediates), which is usually a one-line fix pointing at the fullchain.pem rather than just the leaf.

Whether your certificate actually validates is something a stranger's browser decides the moment it connects, which means it's checkable from outside, and that's what SurfaceCheckr does. It completes the TLS handshake the way a browser would, then reports specifically why trust failed if it did: self-signed, hostname mismatch, untrusted issuer, or an incomplete chain, kept separate from a plain expiry so you know which fix applies. We read what your server presents on connection and nothing more. A certificate that throws a browser warning costs you every visitor who isn't technical enough to click through, and it's the kind of thing that's invisible from inside a network that already trusts your internal CA, which is exactly why checking it from the outside is the version that matches what your users see.

Find it before someone else does.

Paste your domain. The grade and issue count are free, and you'll see in a couple of minutes exactly what's reachable from outside.