SSL Certificate Stuck Pending After Custom Domain Setup

You bound a custom domain on Vercel / Firebase / Netlify but SSL stays "pending." Diagnose DNS, CAA, and Cloudflare-proxy causes and fix it fast.

You bound your custom domain on Vercel / Firebase / Netlify. The dashboard shows “SSL certificate pending,” or the site loads over HTTP fine but HTTPS throws NET::ERR_CERT_AUTHORITY_INVALID. Thirty minutes pass, then an hour.

Fastest fix: all three platforms use Let’s Encrypt, which issues a cert only after it can (1) resolve your domain to the platform and (2) complete an ACME challenge (usually HTTP-01), which fetches http://yourdomain.com/.well-known/acme-challenge/<token>. So check two things first: run dig to confirm DNS points at the platform (not your old host), and if the domain sits behind Cloudflare’s proxy (orange cloud), switch it to “DNS only” (grey cloud). Those two account for most stuck certs. Everything below is the ordered checklist to clear the rest.

One reassuring fact: a “pending” status for under an hour is normal. Netlify retries every 10 minutes for the first 24 hours; Firebase can take up to 24 hours. Don’t start surgery until DNS is actually correct.

Which bucket are you in?

SymptomMost likely causeJump to
dig returns your old host’s IPDNS not propagated / wrong recordCause 1, 4
Cert never issues, domain behind CloudflareOrange-cloud proxy intercepts challengeCause 3
Dashboard error mentions CAACAA record blocks Let’s EncryptCause 2
Firebase status stuck “Needs setup” / pendingConflicting A / CNAME / AAAA recordsCause 4, 6
Dashboard says “Domain not verified”Ownership TXT not addedCause 5
Cert issued elsewhere but browser still errorsStale HSTS in your browserCause 7

Common causes

Ordered by hit rate, highest first.

1. DNS isn’t propagated yet

The cert issuer needs to fetch http://yourdomain.com/.well-known/acme-challenge/<token>. If DNS hasn’t reached the issuer’s resolver yet, the challenge fails and the platform retries later.

How to spot it:

dig yourdomain.com +short

If it doesn’t yet return the platform’s IP/CNAME, DNS isn’t there. Cross-check from outside your own resolver with dnschecker.org or Google’s Admin Toolbox Dig — propagation is uneven across regions, and the issuer may query a resolver that hasn’t updated.

2. CAA record blocks Let’s Encrypt

If your zone has a CAA record like 0 issue "digicert.com", only DigiCert may issue. Let’s Encrypt requests are rejected and the platform shows a CAA error.

How to spot it:

dig CAA yourdomain.com +short

If you see CAA records and none allow letsencrypt.org, that’s it. Note: a domain with no CAA record lets any CA issue, which is the safe default. (Watch your apex and any parent zone, since CAA is inherited.)

3. Cloudflare proxy (orange cloud) intercepts the challenge

When Cloudflare proxies your DNS (orange cloud), it terminates TLS itself and sits in front of your origin. The platform can’t serve its HTTP-01 challenge response, and Cloudflare may serve a cached/redirected response instead, so validation fails. Netlify states this plainly: it “must handle TLS termination to be able to provision a certificate,” so any fronting service has to be disabled first.

How to spot it: In Cloudflare’s DNS table, the A/CNAME for your apex (and www) shows the orange cloud (Proxied). For initial issuance it must be grey (DNS only).

4. Wrong record type or stale conflicting record

Each platform expects specific record types and values. A CNAME where an A is required, or a leftover record from your old host, blocks issuance.

  • Vercel apex: an A record. 76.76.21.21 still works, but Vercel now generates per-project values — read the exact ones on Project → Settings → Domains, or run vercel domains inspect yourdomain.com. www: CNAME to cname.vercel-dns.com (newer projects may show a *.vercel-dns-NNN.com target — use whatever the dashboard shows).
  • Netlify apex: A to 75.2.60.5. www: CNAME to <your-site>.netlify.app.
  • Firebase: use the exact A records shown in the Connect Domain dialog, and remove every conflicting A, CNAME, and AAAA that points elsewhere — Firebase cannot provision a cert while any of them exist.

How to spot it: compare dig output to the values your dashboard shows; don’t improvise record types.

5. Domain isn’t verified on the platform

Some setups require an ownership TXT record before issuing SSL. Add the domain but skip verification, and the dashboard can say “pending” indefinitely.

How to spot it: Look for a “Verify ownership,” “Domain not verified,” or Verify prompt in the platform dashboard, and add the TXT it gives you.

6. AAAA record points elsewhere

You have a correct A record but an AAAA (IPv6) record pointing at the old host. The issuer may prefer IPv6 and hit the wrong target.

How to spot it:

dig AAAA yourdomain.com +short

If AAAA points elsewhere, remove or update it. (Firebase in particular fails issuance while a stray AAAA exists.)

7. Stale HSTS in your browser

The cert may already be issued, but your browser remembers an old HSTS entry and refuses to load anything but the broken HTTPS. This doesn’t affect issuance; it just masks success.

How to spot it: Browser still shows NET::ERR_CERT_AUTHORITY_INVALID after the dashboard reports the cert issued. In Chrome, clear it at chrome://net-internals/#hsts → “Delete domain security policies.” Also retry in an incognito window.

Shortest path to fix

Step 1: Verify DNS via dig

dig yourdomain.com +short            # A record for apex
dig www.yourdomain.com +short        # resolves the www CNAME chain

Both should return the platform’s expected values. If they show your old host’s IP, DNS isn’t fully there — confirm globally on dnschecker.org before doing anything else.

Step 2: Check CAA

dig CAA yourdomain.com +short

If you see something restrictive like 0 issue "digicert.com", either add 0 issue "letsencrypt.org" or remove the CAA record entirely (no CAA = any CA may issue). To lock issuance to one platform safely, pin its ACME account instead of just the CA — e.g. Netlify documents an accounturi CAA value tied to its Let’s Encrypt account.

Step 3: Switch Cloudflare to “DNS only” temporarily

In Cloudflare → DNS → Records → for the apex and www, click the orange cloud so it turns grey (DNS only). Wait 1-2 minutes, then re-trigger issuance in the platform dashboard.

Once the cert is issued you can re-enable the proxy (orange cloud). Renewal works through Cloudflare because platforms switch to DNS-01 or use cached authorizations. If you must keep the orange cloud on during issuance, an alternative is a Cloudflare Configuration Rule forcing the /.well-known/acme-challenge/* path to plain HTTP with caching off, but flipping to grey for a couple of minutes is simpler.

Step 4: Confirm record types and values match the dashboard

Pull the exact values from your platform and match them with dig:

  • Vercel: vercel domains inspect yourdomain.com (or Project → Settings → Domains).
  • Netlify: Domain management → the records shown for your site (apex A 75.2.60.5, www CNAME <site>.netlify.app).
  • Firebase: the A records in the Connect Domain dialog; delete every other A/CNAME/AAAA.

Never use a CNAME at the apex — DNS forbids it at a zone root (RFC 1034). Use A/ALIAS/ANAME per your DNS provider.

Step 5: Re-trigger cert issuance

After fixing DNS / CAA / proxy:

  • Vercel: Project → Settings → Domains → click Refresh, or remove and re-add the domain.
  • Netlify: Domain management → HTTPSVerify DNS configuration, then Provision certificate.
  • Firebase: Hosting → click Verify in the Connect Domain dialog; status then advances on its own (no manual cert button).

Step 6: Wait, and don’t thrash

Most platforms re-attempt on a fixed cadence: Netlify retries every 10 minutes for the first 24 hours; Vercel re-checks within minutes; Firebase can take up to 24 hours. Don’t keep removing and re-adding the domain — that resets your place in the issuance queue and slows things down.

Step 7: How to confirm it’s fixed

When the cert is live, verify from a clean context, not just the dashboard:

curl -svo /dev/null https://yourdomain.com 2>&1 | grep -Ei 'subject:|issuer:|expire'

You should see a valid issuer (e.g. Let’s Encrypt / R-series) and a future expiry. Or open the site in an incognito window — a padlock with no warning means it’s done. If the browser still errors but curl is happy, you’re hitting cached HSTS (Cause 7).

Step 8: If still stuck, contact platform support

After 4+ hours with verified DNS, CAA clear, and proxy off, file a support ticket. Include:

  • Domain name
  • dig yourdomain.com +short and dig CAA yourdomain.com +short output
  • Timestamp when you added the domain
  • A screenshot of the dashboard’s exact error/status

Prevention

  • Don’t set CAA records unless you have a reason; if you do, include every CA your platform might use (Let’s Encrypt, Sectigo, etc.) or pin the platform’s ACME accounturi.
  • Don’t enable the Cloudflare proxy until after the initial cert is issued.
  • dig before you stare at the dashboard — if DNS is wrong, the cert can’t issue.
  • Use the exact record types and values your platform shows; never substitute CNAME for A at the apex.
  • Delete leftover A/CNAME/AAAA records from any previous host before pointing DNS at the new one.
  • Keep a domain-setup.md runbook with the precise steps and values for your platform.

FAQ

How long should SSL provisioning take? Usually minutes to an hour once DNS is correct. Netlify auto-retries every 10 minutes for the first 24 hours; Firebase quotes up to 24 hours. If it’s been under an hour with correct DNS, just wait.

It’s been hours and still pending — what’s the single most common cause? DNS not fully propagated to the issuer’s resolver, or the domain still behind Cloudflare’s orange cloud. Re-check dig from dnschecker.org and confirm the cloud is grey.

Do I have to turn off the Cloudflare proxy forever? No. Switch it to grey (DNS only) just for initial issuance, then turn it back on. Renewals use DNS-01 or cached authorizations and work fine through the proxy.

Will adding a CAA record speed things up? Only if a restrictive CAA was blocking issuance. If you have no CAA at all, leave it — any CA can issue. Add 0 issue "letsencrypt.org" only when you need to whitelist Let’s Encrypt explicitly.

My cert shows as issued but the browser still says NET::ERR_CERT_AUTHORITY_INVALID. That’s stale HSTS/cache on your machine, not an issuance problem. Clear HSTS (chrome://net-internals/#hsts) and retry in incognito.

Can I use a CNAME for my apex/root domain? No — DNS forbids a CNAME at a zone apex (RFC 1034). Use an A record, or your DNS provider’s ALIAS/ANAME flattening if you need CNAME-like behavior at the root.

Tags: #Troubleshooting #DNS #Debug #SSL