• Indonesian
  • English
  • GitHub Pages Custom Domain: Complete Setup Guide 2026

    Kecepatan:
    ⏱ 11 min read
    Difficulty: Beginner
    Last Updated: August 2026
    Tested On: GitHub Pages user site, .com domain, Cloudflare DNS, 2026

    How to Set Up a Custom Domain on GitHub Pages: Complete Step-by-Step Guide

    Skip the fluff — here’s the deal. A few months back, a client of mine burned two full days fighting GitHub Pages because he’d typed his domain into Settings but never created the CNAME file. Two days, gone, over a single missing file. I’ll make sure that doesn’t happen to you. This is the straightforward github pages custom domain setup walkthrough — no extra steps, no fluff, just what actually works.

    Think of your repo as a physical shop. GitHub hands you a free storefront at username.github.io the moment you enable Pages. A custom domain is your own sign and your own mailing address. To make it real you need two things: the sign hung on the storefront (that’s the CNAME file), and your address registered in the city directory so the postman knows where to deliver (that’s DNS). Missing either one and mail just… doesn’t arrive. Nothing about this is optional.

    Why GitHub Pages Custom Domain Setup Fails

    The failure always comes down to one of three places, and the annoying part is the error messages rarely tell you which one. First, the CNAME file — either it doesn’t exist, it’s in the wrong branch, or it doesn’t match what you typed in Settings. Second, the DNS records — wrong type, wrong target, or pointed at an outdated IP from an old tutorial. Third, timing — DNS propagation and TLS certificate provisioning both take time, and impatient people keep touching things that were already fine. Nail all three and you’re done; skip one and you’ll be chasing symptoms all day.

    The symptoms you’ll see are pretty consistent. “Domain is already assigned to another site” means GitHub thinks that domain belongs to a different repository of yours. “DNS has not resolved yet” means your records haven’t propagated, or they’re just wrong. And the classic HTTPS error, “Certificate not active,” only means Let’s Encrypt hasn’t finished issuing your cert yet — usually because DNS still wasn’t resolving when GitHub first tried. You can chase all three at once, or you can follow the order below and avoid most of them entirely.

    Here’s the thing I tell everyone: treat this as a pipeline. CNAME first, then DNS, then wait, then HTTPS. If you jump the line — say, you enable Enforce HTTPS before DNS resolves — you’ll just create extra work and longer wait times. Trust me, I’ve seen people toggle that checkbox for an hour straight expecting it to fix the DNS. It won’t. Order matters, and that’s the entire trick to this. Get the sequence right once, and every future domain change becomes a ten-minute job.

    GitHub Pages Custom Domain Setup: Step by Step

    I’ll assume you already have a working GitHub Pages site (a user site at username.github.io or a project site on the gh-pages branch) and a domain where you can edit DNS records. If either of those is missing, sort it out first — you can’t wire up what doesn’t exist yet.

    Step 1: Check Your Repository Layout

    User sites need the repo named exactly <username>.github.io. Project sites can publish from the gh-pages branch or a /docs folder. Whatever you use, the rule below applies to the branch that actually gets published. Write this down somewhere — it’s the branch you’ll keep coming back to in the next few steps.

    Step 2: Add the CNAME File

    Create a file named CNAME — all caps, no extension — in the root of your repository, in the branch that Pages publishes from. The entire file is one line: your domain, no https://, no trailing slash.

    example.com

    Want www instead? Then write www.example.com. Whatever you put here must match, character for character, what you’ll type in Settings later. Commit and push, then double-check the file is actually visible in the repo on GitHub’s website. Skipping files is a classic move — I’ve done it myself more than once.

    Using Jekyll or a custom build? Put the CNAME file in the branch that Pages publishes from. If you publish from a /docs folder or the gh-pages branch, the CNAME must live there — not just in your source branch.

    Step 3: Enable the Custom Domain in Settings

    Open the repo, go to Settings > Pages. Under Custom domain, type the same domain you put in the CNAME file and hit Save. If everything lines up, you’ll get a success message with a green check. If you get an error instead, go back to Step 2 — it’s almost always the CNAME file, and occasionally DNS that hasn’t caught up. Leave the Enforce HTTPS checkbox alone for now. We’ll come back for it in Step 6.

    Step 4: Point Your DNS

    Here’s where most of the confusion lives, so let’s keep it simple. You have two possible setups, and they use different records. Figure out which one applies to you, then add exactly those records.

    Using the apex domain (example.com)? Then you need four A records pointing at GitHub’s IPs. These IPs are official and fixed — ignore tutorials that list different ones:

    Record Name Value TTL
    A @ 185.199.108.153 3600
    A @ 185.199.109.153 3600
    A @ 185.199.110.153 3600
    A @ 185.199.111.153 3600
    AAAA @ 2606:50c0:8000::153 3600
    AAAA @ 2606:50c0:8001::153 3600
    AAAA @ 2606:50c0:8002::153 3600
    AAAA @ 2606:50c0:8003::153 3600

    Using www.example.com? Then one CNAME record is all you need, pointing at your user site:

    Record Name Value TTL
    CNAME www username.github.io 3600

    Want both example.com and www.example.com to work? Combine them: four A records (plus the AAAA block if you want IPv6 support) for the apex, plus one CNAME for www. That’s the setup I’d recommend for 95% of people — it’s clean, and both URLs land on the same site.

    github pages custom domain setup DNS A record

    Before adding records, check for conflicts. If www already has a CNAME pointing at an old host, delete or update it first — one record name can’t have two targets. And if your registrar has a “domain forwarding” feature active on top of this, turn it off; it will fight with GitHub’s own redirects.

    Step 5: Wait for Propagation and Verify

    DNS doesn’t update instantly, and that’s fine — plan for it. To check whether your records are correct, use dig or nslookup:

    dig example.com +short

    For the apex, you want to see the four 185.199.x.x IPs above. Anything else means a wrong record or stale cache. For www:

    dig www.example.com +short

    That one should print username.github.io. If both match, your DNS is done and GitHub will start provisioning a TLS certificate. One note on TTL: 3600 seconds means changes take up to an hour to spread everywhere. If you’re about to make a lot of changes, drop the TTL to 300 first — future you will appreciate being able to test quickly instead of waiting an hour per attempt.

    Step 6: Enforce HTTPS

    Head back to Settings > Pages. Once your domain shows as active and DNS resolves correctly, GitHub begins issuing a free Let’s Encrypt certificate automatically. Give it anywhere from a few minutes to a few hours, then tick Enforce HTTPS. If you tick it before the certificate exists, you’ll just sit in error land waiting. Sequence: DNS resolves, domain active, cert issued, then enforce.

    Once enforced, verify with curl:

    curl -I https://example.com

    You want HTTP/2 200 or a 301 redirect to the HTTPS version. If you get a certificate error, provisioning is still running — check again in a few hours. If it’s still failing after 24 hours, something in DNS or the CNAME is off. Back to steps 2-4 you go.

    Troubleshooting GitHub Pages Custom Domain Issues

    Here’s the troubleshooting table I keep in my head (and now, in print) for when things go sideways. Save it, it’ll save you a headache.

    Symptom Likely Cause Fix
    “Domain is already assigned to another site” The domain is set as custom domain on another repo Check all your repos, remove the old custom domain
    “DNS has not resolved yet” Records not added or not propagated Verify with dig, wait up to 24 hours
    “Certificate not active” TLS provisioning still in progress Confirm DNS resolves, wait a few hours
    Site works but redirects to username.github.io CNAME file missing or in the wrong branch Put CNAME in the root of the published branch
    404 despite correct DNS Pages source or branch misconfigured Check Settings > Pages source

    The single most common failure I see in the field is a mismatched CNAME — someone types example.com into Settings but the CNAME file says www.example.com, or the file lives on the wrong branch entirely. Both must match, and the file must be in the published branch. Also worth checking: if you manage multiple environments, make sure the CNAME that got pushed actually came from the right one.

    Pro Tips From the Field

    A few small things that quietly save people hours:

    • Pick one canonical hostname. Choose www or non-www, make it the primary, and let GitHub’s automatic redirect handle the other. Two active hostnames pointing at the same site without a defined canonical splits your SEO signals and confuses users.
    • Verify DNS from multiple vantage points. Your ISP’s resolver results alone prove nothing. Use an external lookup tool so you’re not debugging a stale local cache.
    • Only trust GitHub’s official IPs. The four 185.199.x.x addresses above are current and stable. Old tutorials floating around still list IPs from years ago — skip them.
    • Lower the TTL before big changes. A 300-second TTL means changes propagate in minutes, so you can iterate fast during setup, then raise it back once everything is stable.

    If DNS propagation itself has ever confused you — why it’s slow, how it actually works — I wrote a deep dive you’ll want: DNS Propagation Troubleshooting Guide. For more on A and CNAME records specifically, check How to Set Up a DNS A Record. And if you’re thinking about outgrowing GitHub Pages and moving to your own box, read How to Migrate a Website to a VPS before you make the jump.

    FAQ: GitHub Pages Custom Domain

    Q: Why doesn’t my custom domain activate right after I save it?

    Because three separate things have to happen in order: the CNAME file has to be correct, DNS has to resolve to GitHub’s IPs, and GitHub has to issue a TLS certificate. Each step takes time. Give it a full 24 hours before you start changing records — most “problems” are just impatience.

    Q: Should I use www or non-www?

    Technically it doesn’t matter — what matters is consistency. Pick one as your primary and let GitHub redirect the other. Non-www is arguably cleaner for branding, www is fine too. The genuinely bad option is running both without a defined canonical, because it splits your traffic and your SEO signals.

    Q: Why is my TLS certificate stuck on “not active”?

    GitHub uses Let’s Encrypt, and provisioning can take a few hours. First confirm DNS resolves to the right IPs and the CNAME file is correct. If it’s still stuck after 24 hours, re-check DNS from an external tool — a wrong or stale record is the usual culprit.

    Q: Is there a difference between user sites and project sites for custom domains?

    Yes. On a user site (username.github.io), the custom domain applies to everything in that repo. On a project site, the domain applies only to that project, and each project repo needs its own CNAME file. The DNS records and HTTPS setup work identically in both cases.

    Wrap-Up

    Honestly? GitHub pages custom domain setup comes down to three things: a correct CNAME file, the right DNS records (four A records for the apex or one CNAME for www), and the patience to let propagation and certificate provisioning finish. Get those three right and the domain just works. If you want to go deeper on how DNS works and why it frustrates everyone, the DNS propagation guide I linked above has you covered.

    Save this page — custom domains are rarely a one-and-done thing. New domain, migration to a VPS, manual SSL setup… you’ll be back to this exact sequence every time. Bookmark it, follow the order, and you’re done. Go wire up that domain.

    Author: Syslog Solutions — NOC & Server Management Team. We handle 500+ servers daily, from shared hosting to enterprise dedicated infrastructure.