PL-028high or mediumLive posture

TLS certificate is invalid, expired or expires within 21 days

Browsers will block your site, or soon will, because its HTTPS certificate doesn’t check out.

Severity
High or medium
Who can exploit it
Every visitor sees a browser warning; anyone on their network gains
Found by
PatchLabs Live posture: the TLS handshake of the home page load
Lab proof
Not lab-proven: read from the TLS handshake

What it is

Your HTTPS certificate proves to the browser that it is talking to your domain. PL-028 is reported in two strengths. High: the certificate is invalid (it doesn’t cover the hostname, isn’t signed by a trusted authority, or the chain is incomplete) or has already expired. Medium: it is valid today but expires within 21 days.

An invalid or expired certificate puts a full-page warning in front of every visitor. Most leave; the ones who click through have been taught to ignore the one warning that tells them someone is intercepting the connection. That is why an invalid or expired certificate always sets the Live posture grade to F, whatever else passes.

Why AI builders produce it

Managed hosts issue and renew certificates on their own, so certificates rarely expire on a default domain. They expire after a change nobody connected to TLS: DNS moved to a new provider, a CAA record added that doesn’t allow the host’s certificate authority, a domain pointed at two hosts at once, or a certificate uploaded by hand for a launch and forgotten.

What we see

A synthetic example for app.example.com, shortened. Not taken from any real site.

what an expired certificate looks like
$ curl -sI https://app.example.com
curl: (60) SSL certificate problem: certificate has expired

$ openssl s_client -connect app.example.com:443 -servername app.example.com </dev/null 2>/dev/null \
    | openssl x509 -noout -enddate
notAfter=Oct 30 11:02:41 2026 GMT

Check it yourself

check-pl-028.sh
# who issued it, which names it covers, and when it expires
openssl s_client -connect your-app.com:443 -servername your-app.com </dev/null 2>/dev/null \
  | openssl x509 -noout -issuer -enddate -ext subjectAltName

# curl refuses an invalid certificate and says why
curl -sS -o /dev/null https://your-app.com && echo "certificate OK"

# a CAA record can stop renewals: it must allow your host's authority
dig +short CAA your-app.com

Check every hostname you use, including www: each needs its own name on the certificate.

The fix

A managed certificate should renew about a month before it expires without anyone touching it. If yours didn’t, something stopped the host from proving you own the domain. Find that, and the renewal follows.

Vercel

Vercel issues Let’s Encrypt certificates for domains in your project and renews them automatically, as long as the domain’s DNS points at Vercel. Open Settings → Domains: a domain with a configuration warning can’t renew. If you have a CAA record, it must allow letsencrypt.org.

DNS · CAA record (only if you use CAA)
your-app.com.  CAA  0 issue "letsencrypt.org"

Netlify

Netlify also uses Let’s Encrypt and renews automatically while DNS points at Netlify. Under Domain management → HTTPS, use Renew certificate after fixing DNS. If you uploaded your own certificate, Netlify can’t renew it for you: replace it before the date, or switch back to the managed one.

Cloudflare

When the site is proxied, visitors see Cloudflare’s edge certificate, which renews on its own (SSL/TLS → Edge Certificates). Behind it, with Full (strict), your host still needs a valid certificate of its own: if that one expires, visitors get a Cloudflare error page instead of your site. A Cloudflare Origin CA certificate on the host is a long-lived option for that hop.

Lovable

Lovable generates and installs the certificate for a connected custom domain and its documentation says you don’t need to upload or reissue one. If the check fails, the usual cause is DNS: records changed or removed after connecting, or a proxy in front. If the domain goes through Cloudflare, the edge certificate is Cloudflare’s; check it there.

Live posture findings come with the header or setting to change. PatchLabs never changes your hosting or your repo.

How PatchLabs finds it

live posture · report excerpt
[TLS]     app.example.com:443
          issuer  Let's Encrypt
          expires 2026-11-24 · 14 days  FLAG
          medium: renew before it lapses
synthetic exampleLive posture · read from the home page’s response

Live posture reads the certificate from the TLS handshake of the one https:// page load it makes: the issuer, the names it covers, the protocol version and the expiry date, which the report shows as days left. It doesn’t try other ciphers or protocol versions. Daily re-checks on a verified domain mean a renewal that silently fails shows up 21 days before visitors notice.

When the pattern is intended

Never on a public site. A staging host with a self-signed certificate is common, but keep it off the domains people use, and don’t verify it for Live posture.

Why it’s rated high or medium

High when the certificate is invalid or expired: the site is effectively down for most visitors, and the grade is always F. Medium when it expires within 21 days: nothing is broken yet, but a failed renewal is already likely.

Guides

Free check

Does your site have PL-028?

Type your site’s address. The free headers check loads your public home page once, like any visitor, and grades HTTPS, the certificate, security headers, cookie flags and mixed content. No sign-up, and the result isn’t stored.

Free, no sign-upLoads your public home page onlyHow Live posture works

Last reviewed 10 Nov 2026. Finding IDs are stable: link to them freely. Spotted a mistake? Tell us.