dom4in.net
← All resources
Guide · GitHub Pages

Point a custom domain at GitHub Pages

One CNAME for www, four A records for the apex, and a domain verification TXT so nobody can hijack it later — the whole setup is about ten minutes including the HTTPS wait.

The process

The complete path from a working username.github.io site to your own domain with HTTPS enforced. Follow the crumbs in order — the verification step matters even though the site works without it.

Directions

1Verify the domain on your account first

Before touching the repository, go to your GitHub account (or organization) Settings, then Pages, and click Add a domain under Verified domains. This step is easy to skip because the site will work without it, but it is the thing that prevents domain takeover: without verification, anyone can claim your domain on their own Pages site the moment your repo goes private or gets deleted.

GitHub gives you a TXT record with a host like _github-pages-challenge-<username> and a random value. Add it in your DNS host exactly as shown, wait a few minutes, and click Verify. Once it turns green the domain is locked to your account.

Host:  _github-pages-challenge-yourname.example.com
Type:  TXT
Value: 1a2b3c4d5e (random token GitHub shows you)

2Set the custom domain on the repository

Open the repository that serves your Pages site, go to Settings, then Pages. In the Custom domain field enter the domain you want visitors to use — pick one canonical form now, either www.example.com or the bare apex example.com, because GitHub will redirect the other one to it.

Saving this field commits a file named CNAME to the publishing branch. If you deploy with GitHub Actions, make sure your build doesn't wipe that file out on the next deploy — static site generators need it in their output folder (Astro and most others: put it in public/).

3Add the CNAME and apex A records

In your DNS host, point the www subdomain at your Pages hostname with a CNAME. For the apex you cannot use a CNAME at most DNS hosts, so GitHub publishes four fixed A records (and four AAAA if you want IPv6). Add all four — they are anycast addresses, not a priority list.

If your DNS is on Cloudflare, set these records to DNS only (grey cloud) at least until HTTPS is issued. Proxying during certificate issuance makes GitHub's challenge fail, and double-proxying afterwards buys you nothing on a static site.

www.example.com  CNAME  yourname.github.io
example.com      A      185.199.108.153
example.com      A      185.199.109.153
example.com      A      185.199.110.153
example.com      A      185.199.111.153

4Let GitHub run its DNS check

Back on the Pages settings screen GitHub runs a DNS check against the domain you entered. It usually passes within a few minutes, but a fresh record at a slow registrar can take up to an hour. Don't click around re-saving the domain while it's pending — that restarts the check.

5Tick Enforce HTTPS

Once the DNS check passes, GitHub requests a certificate from Let's Encrypt automatically. When the Enforce HTTPS checkbox becomes clickable (this can lag the DNS check by a few minutes to an hour), tick it. From then on every http:// request gets a 301 to https://, which is what you want for both users and search engines.

Common issues & fixes

Enforce HTTPS stays greyed out.

The certificate hasn't been issued yet, usually because DNS just changed or a Cloudflare proxy is intercepting the challenge. Set the records to DNS only, remove and re-add the custom domain to restart issuance, and wait up to an hour.

The CNAME file disappears on every deploy.

Your build pipeline overwrites the publishing branch. Add a CNAME file containing just the domain to your static folder (public/ in most generators) so it ships with every build.

www works but the apex 404s (or vice versa).

Only the domain in the Custom domain field gets served directly; the other form needs its DNS records too. Add the missing CNAME or A records and GitHub will redirect to the canonical form.

Someone else's site is showing on your domain.

This is the takeover scenario — the domain was pointed at Pages but never verified. Verify the domain on your account (step 1) and file a GitHub support ticket to release it.

DNS check fails with an ALIAS/ANAME warning.

Your DNS host put a CNAME-like record on the apex, which conflicts with other apex records like MX. Replace it with the four plain A records and mail keeps working.

Honesty note: articles are drafted with AI assistance, then a human checks each one against the vendor's current setup flow before it publishes — nothing goes live unreviewed. Vendor interfaces still change; if a step looks different, the underlying record is what matters.