Overview
Attach a custom domain to GitHub Pages in dependency order: register it, verify it, add records, confirm resolution, then enforce HTTPS. Out-of-order steps cause a greyed-out “Enforce HTTPS” box or a certificate that covers the apex but not www. This is phase 3 of launch-a-new-site and assumes the site already serves on its *.github.io URL (deploy-quartz-site).
Steps
1. Register the domain in Pages settings
Open the repo’s Settings, Pages, Custom domain, and save the domain. For a branch-based deploy GitHub writes a CNAME file. For a custom Actions workflow no CNAME file is created and any existing one is ignored, so the setting in Pages is the source of truth.
2. Verify the domain
Verify it at the account or organization level (Settings, Pages, Add a domain). GitHub gives you a TXT record to add at the registrar. Verification stops another GitHub user from claiming a subdomain of yours that points at Pages but has no repository attached.
3. Add the DNS records
Apex domain, four A records and four AAAA records:
185.199.108.153 2606:50c0:8000::153
185.199.109.153 2606:50c0:8001::153
185.199.110.153 2606:50c0:8002::153
185.199.111.153 2606:50c0:8003::153
For www, a CNAME to <user-or-org>.github.io, never including the repository name. Do not use wildcard DNS records such as *.example.com; GitHub warns they expose you to domain takeover. If Cloudflare proxies the records, set SSL/TLS mode to Full (strict). Registrar steps: namecheap-dns, cloudflare-dns.
4. Confirm resolution before enforcing HTTPS
dig +short example.com # four 185.199.x.153 addresses
dig +short AAAA example.com # four 2606:50c0:800x::153 addresses
dig +short www.example.com # <user-or-org>.github.io. then the IPs5. Enforce HTTPS last
Tick “Enforce HTTPS” only after apex and www both resolve; the box stays disabled until the certificate exists. The certificate covers whatever resolved when it was issued, so if you added www later, remove and re-add the custom domain to get a certificate for both.
Verify it worked
curl -I https://example.com
curl -I https://www.example.comBoth return 200, or a single redirect to the canonical host, with a valid certificate and no loop. See http-status-codes for anything else.
Common errors
- “Enforce HTTPS” is disabled. DNS has not propagated or the domain is not saved; recheck steps 1 and 4.
- Certificate error on one host only. Re-add the domain after both records resolve.
- The domain reverts or disappears after a deploy. Re-enter it in Settings, Pages; with an Actions workflow, a
CNAMEfile in the output does not set it.