Skip to content

Security basics

Certificate not trusted: the three causes besides expiry

Certificate not trusted, and the date is fine? It names another address, it signed itself, or its chain is missing a link. How to tell which.

Vlad Tkachenko10 min read
A certificate card with its seal and date lit in accent, under an address bar whose name is longer than the amber name on the card.

In short

  • A certificate not trusted by browsers can be perfectly in date. It is refused because it names a different address, because it signed itself, or because it arrived without the certificate that vouches for it.
  • The warning screen is the same one an expired certificate gets, and renewing fixes none of the three. The code printed under the warning tells you which one you have.
  • On Lovable and Vercel, a custom domain shows this warning until its certificate is issued. That wait is normal. A warning that outlasts it means something is stopping the certificate.

Your app loaded fine yesterday. Today somebody sends you a screenshot of a full-page browser warning, "Your connection is not private", and asks whether your site has been hacked. You open the certificate and it is valid until next spring. It has not expired, and you are still looking at a certificate not trusted by the browser.

The obvious move is to renew it, and for this screen it is the wrong one. Each of the three causes below happens to a certificate that is already in date, so a renewal gets you a later expiry date on a certificate that is still refused for some other reason.

In our post on expiry, the certificate is the licence in the shop window, saying this shop really is the one on the sign. A visitor's browser reads three things on that licence before it lets anybody in: the date, the name of the shop it was issued to, and the signature of whoever issued it. Expiry is the date. This article is about the other two.

Why is my certificate not trusted when it has not expired?

Because the name or the signature failed, and the browser puts up the same wall for every one of its checks.

A certificate is trusted only when it names the exact address in the visitor's address bar and was signed by an authority the browser already trusts, with every certificate in between sent along. Fail either and Chrome shows "Your connection is not private" and Firefox "Warning: Potential Security Risk Ahead", exactly as they do for an expired one.

What differs is the small print under the warning. Read it before you change anything:

What Chrome printsWhat Firefox says after AdvancedWhat it meansWhat fixes it
NET::ERR_CERT_COMMON_NAME_INVALIDThe certificate is "not valid for" your addressIt was issued to a different nameA certificate that lists your exact address
NET::ERR_CERT_AUTHORITY_INVALID"The certificate is not trusted because it is self-signed"Nobody vouches for it but the server itselfA certificate from a real authority
NET::ERR_CERT_AUTHORITY_INVALID"its certificate issuer is unknown"The browser cannot connect it to an authority it trustsThe full chain, from a recognised authority
NET::ERR_CERT_DATE_INVALIDThe certificate has expiredThe dateA new certificate

Chrome prints one code for the second and third rows, which is why the certificate itself is worth opening.

If one person reports the warning and nobody else can see it, ask which network they were on. Chrome's source code lists a wifi network that sends its users to a sign-in page as one cause of the name error. That one clears when they sign in to the network.

How do I see what the certificate says?

Open it from the warning and read two fields: who it was issued to, and who issued it.

In Chrome, click Not secure at the left of the address bar and open the certificate from the panel that appears. In Firefox, click Advanced on the warning, then View the site's certificate. The two browsers label the same fields differently:

  • Issued To in Chrome, Subject Name in Firefox, is the name the certificate was made for. The full list of names it covers sits under Subject Alternative Name, and that list is what the browser compares with the address.
  • Issued By in Chrome, Issuer Name in Firefox, is the authority that signed it.

Each of the three causes reads differently there:

  • The certificate names some other address. That is cause 1.
  • Issued To and Issued By are the same name. It signed itself, which is cause 2.
  • It names your address, the issuer is an authority you have heard of, and the browser still refuses it. That is cause 3, the chain.

Cause 1: the certificate is for a different address

The certificate is genuine and in date, and it was issued for another name. It is the licence of a different shop, hanging in your window.

It comes in three shapes:

  • Your domain points at a host that has no certificate for it yet. The host answers with the certificate it does have, issued to a name of its own. Lovable's documentation says so plainly: until the certificate is ready, "the browser shows a security warning instead of your site."
  • The certificate covers one spelling of your address and the visitor typed the other. www.yourapp.com and yourapp.com are two names to a certificate, and each one has to be on its list.
  • Part of your DNS still points at a place you left. An old host, or the parking page your registrar showed before you connected anything, answers on that name with a certificate of its own.
To a certificate, the address with www and the one without are two names. The address in the bar has to be on the list.

On Lovable and Vercel you do not buy or install this certificate yourself. The host issues one for each name you add in its domain settings, once your DNS points that name at the host. Lovable's documentation adds that a certificate bought from your registrar is not used by its hosting at all. Add both spellings, point both at the host, and wait until each shows as live.

Cause 2: the certificate signed itself

Nobody vouches for this certificate except the server presenting it. It is a licence the shopkeeper printed at home.

Every browser refuses one on a public site, and is meant to. A comment in Chrome's source code puts the reason in one line: a self-signed certificate provides no defence against an attacker sitting between your visitor and your app.

You meet it on servers somebody set up by hand: a rented server, a self-hosted tool, a test setting that went live with the app. A builder issues real certificates for the domains you add to it, so a self-signed certificate on a builder-hosted app means something other than the builder is answering on your address. Check where your DNS points before you change anything else.

The fix is a certificate from a real authority. Let's Encrypt issues them free, and it is the authority Vercel uses when it issues yours.

The certificate is for your address and was signed by a real authority, and the server sent it without the certificate in between, so the browser cannot connect it to anybody it trusts. The licence was signed by a branch office, and the letter from head office vouching for that branch is missing from the window.

Mozilla calls a missing intermediate certificate "one of the most common server configuration problems". Firefox now downloads a copy of every trusted intermediate in advance, so that its users stop meeting the error.

That is what makes this cause hard to see: it can look fine on your laptop and fail for somebody else. A browser holding its own copy of the missing link fills the gap. Software that uses only what your server sends has nothing to fill it with. Our scanner is that kind of software, which is why it can report a certificate as untrusted while your own browser shows a padlock.

The same incomplete chain, sent to two visitors. Only the one who already had the missing link can complete it.

On a builder the chain is handled for you. It goes missing on servers configured by hand, and the fix there is to serve the certificate followed by the intermediate, in one file. If you use Let's Encrypt's certbot, that file is fullchain.pem, and the mistake is pointing your server at cert.pem instead. To check from outside, SSL Labs' free server test reports a missing intermediate as a chain issue.

The custom-domain case, in order

When you connect your own domain to a builder, visitors see this warning until the host has a certificate for your name, and the warning is telling the truth. It ends by itself once the certificate is issued.

The order, on Lovable:

  1. Add the domain in Lovable. It sets up both yourapp.com and www.yourapp.com and lists them separately.
  2. Change the DNS records at your registrar to the values Lovable gives you. Lovable says most updates are live within a few hours, and that propagation can take up to 72.
  3. Lovable verifies the domain and issues the certificate. Vercel works the same way: it proves to Let's Encrypt that the name is yours, automatically, as long as the domain points at Vercel.
  4. Open the site once the domain shows as Live, which is Lovable's own advice.
Between pointing your domain at the host and the certificate arriving, the warning is correct. Lovable asks you to contact support if it is still there after 72 hours.

If the warning is still there after 72 hours, Lovable asks you to contact its support. Two settings are worth checking before you write:

  • Look for a CAA record. It is a DNS entry naming which authorities may issue certificates for your domain. One that leaves out your host's authority blocks the certificate, and a subdomain inherits the parent domain's CAA records when it has none of its own. The expiry post meets the same record as a reason a renewal fails; here it stops the first certificate from ever being issued.
  • Look for a proxy in front. If your DNS is at Cloudflare with the orange cloud switched on for the records your host gave you, Cloudflare answers instead of your host. Lovable says it then cannot verify the domain or issue certificates for it, and Lovable and Vercel both say to set those records to DNS only.

What we found across 30,879 apps

Eight had a certificate that no browser would trust, and every one of them was on a domain its owner had connected.

In August 2026 our scan read the certificate of 30,879 live apps: 29,927 on a builder's own subdomain and 952 on a domain of their own. All eight untrusted certificates were among the 952, a little under one in a hundred. None of the apps on a builder's subdomain had one, which fits everything above. On the builder's own address, the builder owns both the name and the certificate.

Our finding records that the certificate failed and not which of the three causes it was, so we cannot tell you how the eight divide. The expired and expiring certificates from the same scan are counted in the expiry post.

To check your own app, our free scan reads the certificate your server sends, from outside, and names this finding when it sees it. It takes about 20 seconds and needs no account.

Catching it the next time something changes

A certificate goes from trusted to refused when something around it changes: a new domain, a DNS move, a proxy switched on. The check that matters is the one that runs after the change.

Scan your app free to see what a visitor's browser is handed today.

  • Reads the certificate your server sends, from outside, along with eight other checks.
  • Names the finding when the certificate is untrusted, and when it is expired or close to it.
  • About 20 seconds, and no account.

Reeve Monitor to hear about it soon after it changes.

  • Checks your app every 60 seconds, and a certificate it cannot trust counts as your app being down, so you are told the way you would be about an outage.
  • Re-runs all nine checks every hour, and emails you when your grade drops.
  • Covers up to three apps.

What to do right now

What to do

  • Read the code under the warning before you renew anything. A date error needs a new certificate. A name or authority error needs something else.
  • Open the certificate and compare the name it was issued to with the address in the bar, and with the name of whoever issued it.
  • On a builder, add both yourapp.com and www.yourapp.com in its domain settings and point both at it.
  • If a new domain still shows the warning after 72 hours, look for a CAA record or a proxy in front of the host before you contact support.
  • On a server you run yourself, serve the full chain and check it from outside with SSL Labs.

When the warning has gone and the app still does not load, the next question is whether it is your app or the platform under it, and is Supabase down, or is it your app walks through how to tell.

FAQ

Why does my site say "not private" when my certificate has not expired?

Because the date is one of three things a browser checks, and the other two fail on their own. The certificate also has to name the exact address the visitor typed, and it has to be signed by an authority the browser trusts, with every certificate in between sent along. A certificate that fails either check gets the same full-page warning an expired one does, and renewing it changes nothing.

What is a certificate name mismatch?

A certificate issued for one address, presented on another. Chrome reports it as NET::ERR_CERT_COMMON_NAME_INVALID and Firefox says the certificate is not valid for your address. The certificate itself is usually real and in date. It belongs to a different name, often your host's own, which is what a host answers with on your domain before it has issued one for you.

Why does www work and the bare domain not?

Because to a certificate they are two different names. Either the certificate lists only one of them, or the DNS for the other still points somewhere else, such as your registrar's parking page or an old host, which answers with a certificate of its own. Lovable connects both and lists them separately, so check that each one shows as live.

How long does a custom domain certificate take?

Lovable says domain setup typically completes within a few minutes but can take up to several hours, that DNS changes may take up to 72 hours to propagate, and to contact its support if the certificate has not been issued after 72 hours. Until it is issued, visitors see a security warning instead of your site.

Is a self-signed certificate ever fine?

On your own machine, for development, yes. On a site the public visits, no. Every visitor's browser refuses it, and Chrome's own source code notes that a self-signed certificate provides no defence against an attacker sitting between the visitor and the site.

Written by

Vlad Tkachenko

Founder, Reeve

I spend my time looking at apps built with Lovable, Bolt, v0, Cursor and Replit, and at the short list of mistakes that keep turning up in them.

More about the author

Read next

All articles

Not sure where your own app stands?

Run a free scan and get a plain-language grade from A to F in about 20 seconds. No account, no card.

Scan your app free

Automated external check, not a full audit. Absence of findings is not a guarantee of safety.