Pointing a custom domain at GitHub Pages is a two-part job: you add DNS records at your registrar so the name resolves to GitHub's servers, and you tell GitHub which domain to serve so it can issue a TLS certificate. The DNS side differs depending on whether you are using an apex domain like example.com or a www subdomain, and the HTTPS step will not succeed until DNS has fully resolved. Here is exactly what to publish and how to confirm each step before you flip on the certificate.
Apex domain vs www subdomain
The single most important decision is which host you treat as primary. An apex (or root) domain has no subdomain label in front of it. Because the DNS rules forbid a CNAME at the apex, you must use A and AAAA records there. A www subdomain, by contrast, is allowed to use a CNAME, which is simpler and self-healing if GitHub ever changes IP addresses. Many people publish both so the site works either way.
| You want | Record type | Points to |
|---|---|---|
| example.com (apex) | A and AAAA | GitHub Pages IP addresses |
| www.example.com | CNAME | username.github.io |
Records for an apex domain
Create four A records for the apex, all with the same host (@ or blank, depending on your provider). These four addresses are GitHub's current Pages anycast IPs.
| Type | Host | Value |
|---|---|---|
| A | @ | 185.199.108.153 |
| A | @ | 185.199.109.153 |
| A | @ | 185.199.110.153 |
| A | @ | 185.199.111.153 |
For IPv6 visitors, add the matching AAAA records. GitHub recommends keeping the A records even when you add AAAA, because IPv6 adoption is still uneven.
| Type | Host | Value |
|---|---|---|
| AAAA | @ | 2606:50c0:8000::153 |
| AAAA | @ | 2606:50c0:8001::153 |
| AAAA | @ | 2606:50c0:8002::153 |
| AAAA | @ | 2606:50c0:8003::153 |
Confirm all four A records resolve:
$ dig A example.com +short
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
Record for the www subdomain
The www host uses a single CNAME pointing to your GitHub Pages default domain, which is your username or organization name followed by .github.io. Use the username form even for a project site; do not append the repository name here.
| Type | Host | Value |
|---|---|---|
| CNAME | www | username.github.io |
Verify the CNAME chain:
$ dig CNAME www.example.com +short
username.github.io.
The CNAME file in your repository
When you set a custom domain in the repository's Pages settings, GitHub commits a file literally named CNAME (all capitals, no extension) to the root of your published branch. It holds the single domain you entered. If you build the site with a static generator, make sure your build does not wipe this file on each deploy; many frameworks need the domain added to a config value so the file survives. The contents are simply:
example.com
Setting the domain in GitHub
- Open the repository, go to Settings > Pages.
- Under Custom domain, enter your domain and save. This writes the CNAME file.
- Wait for the DNS check to pass. GitHub queries your records and shows a green confirmation once they resolve.
- Only after the check passes, tick Enforce HTTPS.
Why the HTTPS step depends on DNS
GitHub provisions a free Let's Encrypt certificate for your domain, but it can only do that after your DNS points at GitHub, because the certificate authority validates control by reaching the domain. If you tick Enforce HTTPS too early, the option is greyed out or you see a certificate error, and the fix is almost always patience: the records have not propagated to the resolver GitHub is using yet. This is the moment where a propagation check saves real frustration, because it tells you whether the delay is on GitHub's side or simply caching on yours.
Which host becomes primary
When you publish both the apex records and the www CNAME, GitHub picks one as canonical based on the value in the CNAME file and redirects the other to it. If the file contains example.com, visitors to www.example.com are redirected to the bare apex, and vice versa. Decide which form you want in the address bar, set that exact value as the custom domain in the repository, and let GitHub handle the redirect. There is no SEO penalty either way; what matters is that one of them is canonical and the other consistently forwards.
A note on Cloudflare and other proxies
If your DNS is behind a proxy such as Cloudflare's orange cloud, the proxy terminates the connection and GitHub never sees the visitor's request directly, which can interfere with GitHub's own certificate provisioning. The simplest reliable setup is to keep the Pages records in DNS-only mode (grey cloud) so GitHub can issue and serve its own certificate. If you do proxy, you must manage TLS at the proxy and set its SSL mode to full, or the two certificate layers will conflict.
Common mistakes
- Using a CNAME at the apex. It is invalid DNS and breaks other records at the root such as MX. Use the four A records instead.
- Pointing www at the repository URL. The CNAME target is
username.github.io, neverusername.github.io/repo. - A build that deletes the CNAME file. If HTTPS keeps turning itself off, your deploy is overwriting the file every push.
- Stale A records from a prior host. Remove any old A records so visitors are not split between two servers.
- Enforcing HTTPS before the certificate exists. Let the DNS check pass first, then enable it.
A quick end-to-end test
Once records are live and HTTPS is enforced, test both hosts from the command line and in a browser. A clean result returns the GitHub IPs for the apex and follows the CNAME for www, and both load over HTTPS without a warning.
$ dig example.com +short
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
$ curl -sI https://www.example.com | head -n 1
HTTP/2 200
Confirm it everywhere before you trust it
A lookup on your own machine only shows one resolver's view, and that is exactly the gap that makes the HTTPS step feel random. After you publish the A, AAAA, and CNAME records, run the domain through the Valla DNS propagation checker to confirm they have gone live across regions, which is the signal that GitHub will be able to issue your certificate. If you are pairing the site with email on the same domain, our guides on apex CNAME alternatives and on choosing TTL values before a migration will help you keep the rest of the zone healthy. Publish the records, verify them, then enforce HTTPS with confidence.