Connect a custom domain to Firebase Hosting (2026 guide)

Point your domain at Firebase Hosting with the exact TXT, A and AAAA records, dig verification commands, and fixes for the Needs setup loop and stuck SSL.

Firebase Hosting gives you a free *.web.app URL by default. To serve your site on yourbrand.com you add the domain in the console, prove ownership with a TXT record, then point traffic with A (and AAAA) records. Done in the right order it takes about 15 minutes plus DNS propagation; done in the wrong order you can spend an afternoon staring at a “Needs setup” badge that never flips. The records and dig checks below are what separate the two.

This works on the free Spark plan, which permits commercial sites, and the SSL certificate is issued free via Let’s Encrypt. As of June 2026 Firebase serves custom domains through a Fastly-backed edge, which is why a few of the failure modes below mention Fastly errors.

TL;DR

Add the domain in Firebase, add the TXT record and wait for it to resolve, click Verify, then add the two A records (and AAAA records) Firebase shows you. Delete every stale A/AAAA/CNAME that points at a previous host first, or SSL will never provision. Keep the TXT record in place permanently; Firebase reuses it to renew the certificate.

Who this is for

  • Your *.web.app URL works and you want a real brand domain.
  • You own the domain at a registrar (Cloudflare, Namecheap, Porkbun, Squarespace, etc.).
  • You are comfortable editing DNS records, which is the only manual part.
  • You want both the apex (yourbrand.com) and www to resolve, not just one.
  • You need free SSL and do not need a wildcard certificate (Firebase Hosting does not issue wildcards).

Quick setup vs Advanced setup

The “Add custom domain” wizard offers two modes, and choosing wrong is a common time sink:

ModeUse whenWhat it does
Quick setupNew domain, or one with no live traffic you care aboutVerifies ownership and hands you A records in one pass; brief downtime is acceptable
Advanced setupDomain already serving production trafficVerifies ownership, provisions the certificate, and only then asks you to switch A records, so there is no SSL gap

If you are migrating a live site, pick Advanced setup. It splits the flow into ownership, certificate, then traffic, so visitors never hit an un-provisioned cert.

Before you start

  • Lower the TTL on existing DNS records to 300 seconds at least 24 hours before the switch, so old answers expire fast.
  • Remove any old A, AAAA, or CNAME records that point at a previous host. Firebase cannot issue a certificate while a conflicting record exists.
  • Have your Firebase project ID and the target domain on hand.

Step by step

  1. Add the domain in the Firebase Console. Console → Hosting → Add custom domain → enter yourbrand.com. Quick setup shows a TXT verification record. The value is unique to your project; Advanced setup uses the form hosting-site=[your-site-id]:
Host:  @  (or yourbrand.com)
Type:  TXT
Value: hosting-site=your-site-id        (copy the exact value Firebase shows)
TTL:   300
  1. Add the TXT record at your registrar. Cloudflare example via API, so the step is reproducible:
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
  -H "Authorization: Bearer $CF_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "type": "TXT",
    "name": "@",
    "content": "hosting-site=your-site-id",
    "ttl": 300
  }'
  1. Confirm the TXT has propagated before you click Verify. Firebase allows up to 24 hours for the record to spread, but it is usually a few minutes:
dig +short TXT yourbrand.com @1.1.1.1
# "hosting-site=your-site-id"
  1. Click Verify. Firebase then shows the A records that point the apex at its edge. As of June 2026 the documented example IP is 199.36.158.100; the console shows two addresses, and these values can change, so copy whatever the console gives you rather than hardcoding:
Host:  @          Type: A      Value: 199.36.158.100
Host:  @          Type: A      Value: 199.36.158.101

To serve IPv6 as well, add the matching AAAA records the console lists (the documented example is 2620:0:890::100). For the www subdomain you can either point a CNAME at your Hosting site or use the same A/AAAA records:

Host:  www        Type: CNAME  Value: your-project.web.app
  1. Add the A/AAAA (or CNAME) records and verify resolution from two resolvers:
dig +short A yourbrand.com @1.1.1.1
# 199.36.158.100
# 199.36.158.101

dig +short A yourbrand.com @8.8.8.8        # cross-check a second resolver
dig +short CNAME www.yourbrand.com @1.1.1.1
# your-project.web.app.

If you see extra IPs from a previous host, delete those stale records. DNS will round-robin across live and dead targets and routing will flap.

  1. Wait for the status to flip to “Connected”. SSL provisions automatically, usually within a few hours and up to 24 hours after the A records resolve. Probe the certificate with curl:
curl -vI https://yourbrand.com 2>&1 | grep -E 'subject:|issuer:|HTTP'
# subject: CN=yourbrand.com
# issuer: C=US, O=Let's Encrypt, CN=...
# HTTP/2 200
  1. Add the second variant. If you added the apex first, add www now (or the reverse). Firebase provisions a certificate for it and auto-creates a 301 redirect to your primary domain.

  2. Confirm redirects in an incognito window:

curl -sI http://yourbrand.com       | head -2
# HTTP/1.1 301 Moved Permanently
# Location: https://yourbrand.com/

curl -sI https://www.yourbrand.com  | head -2
# HTTP/2 301
# location: https://yourbrand.com/   (if apex is canonical)
  1. Update Search Console, sitemap, and canonical tags. Verify the new domain as a Domain property, then resubmit the sitemap so Google picks up the new canonical surface.

Launch checklist

  • The TXT verification record is still present (keep it permanently for cert renewal).
  • A/AAAA or CNAME records resolve correctly from at least two resolvers (@1.1.1.1 and @8.8.8.8).
  • No stale A/AAAA/CNAME records from a previous host remain.
  • The SSL certificate subject matches the requested domain, confirmed with curl -vI.
  • Both apex and www are registered in Firebase Hosting: one canonical, one redirecting.
  • Search Console has the new domain verified as a Domain property.
  • A browser test or Lighthouse run shows no mixed-content warnings.

Common pitfalls

  • Adding the A records but skipping TXT. Verification stays pending forever. Re-copy the exact TXT value and confirm it with dig +short TXT.
  • Leaving old A or AAAA records that point at a previous host. Firebase cannot provision the certificate while a conflicting record exists, and DNS will return both targets. Detection: dig +short A (and dig +short AAAA) returns extra addresses.
  • Using a CNAME on the apex domain. Most registrars forbid it. Use A records, or Cloudflare’s CNAME flattening.
  • Registering only apex or only www, then losing traffic from the other variant.
  • Aggressive DNS caching at the registrar. Clear the registrar’s cache or wait for the lowered TTL to expire.
  • Deleting the TXT record after going live. Firebase reuses it to renew the certificate. Keep it in place.
  • Enabling Cloudflare’s proxy (“orange cloud”) before SSL is issued. Set the record to “DNS only” (grey cloud), let Firebase issue the cert, then re-enable the proxy.
  • The “Needs setup” loop. A documented case from February 2026 saw a domain cycle endlessly between “Needs setup”, “Custom domain has been set up”, and “Certificate provisioning”, while the live URL returned a Fastly “unknown domain” error even with correct DNS. When DNS verifies but the badge will not settle, removing and re-adding the custom domain in the console usually clears the stuck state.

FAQ

  • How long does SSL take? Usually under an hour, and up to 24 hours per Firebase’s documented limit, measured from when your A records resolve. If it is still stuck after 24 hours, re-check DNS and delete any conflicting A/AAAA records.
  • Should I make apex or www primary? As of June 2026 most indie sites use the apex as primary. Pick one, set it as canonical everywhere (Search Console, sitemap, rel="canonical" tags), and let the other 301 to it.
  • Do I really have to keep the TXT record? Yes. Unlike one-off ownership checks, Firebase keeps reading the hosting-site TXT record to authorize SSL renewals. Removing it can break the next renewal.
  • Can I move from another host without downtime? Yes. Lower the TTL on existing records to 300 seconds first, validate the new setup on a Firebase preview channel, then switch the records. For zero SSL gap, use Advanced setup so the certificate provisions before you redirect traffic.
  • Why does the dashboard still say “needs setup” after I added records? Either propagation is incomplete or the record values do not match exactly. Re-copy from the console and verify with dig. If DNS is correct but the loop persists, see the Fastly “Needs setup” note in pitfalls above.
  • Why does the same domain work on Vercel in minutes but fail on Firebase? Different ownership models. Vercel auto-issues certificates once the CNAME or A record resolves; Firebase needs the separate TXT verification step first (why a domain works on Vercel but not Firebase).
  • Can I put Cloudflare in front of Firebase? Yes. Set the Cloudflare DNS record to “DNS only” (grey cloud) during certificate issuance, then switch it to “Proxied” (orange cloud) afterward.

Tags: #Indie dev #Firebase #Hosting #Domain #DNS #SSL