⚠️ Note (August 2026): This site now uses Cloudflare Pages (not GitLab Pages). The GitLab Pages verification TXT record described below is no longer needed. The DNS debugging lessons still apply to any custom domain setup.

I was updating my GitHub profile README when I noticed the blog link was dead. Not a typo, not a certificate warning — a plain 401 Unauthorized. My own domain was redirecting strangers to a GitLab login page. The worst part? I had caused it myself three days earlier.


The DNS Migration That Started It

My blog lives on GitLab Pages with a custom domain. For months, Spaceship DNS (my previous registrar’s DNS service) handled the records. I decided to move everything to Cloudflare for better caching, analytics, and the free proxy layer.

The migration looked simple:

Step Record Action
1 A records Point nurazhar.com to Cloudflare IPs
2 CNAME / A Route www to Pages
3 TXT verification Add GitLab Pages verification code
4 SSL/TLS Enable Cloudflare flexible or full

I completed steps 1, 2, and 4. Step 3 vanished from my checklist.


DNS History in One Timeline

That missing TXT record sat at _gitlab-pages.nurazhar.com. Without it, GitLab could not prove I still controlled the domain. The result was a silent failure: the blog loaded fine for me because I was logged into GitLab, but every public visitor hit a login wall.


Why the 401 Was So Misleading

A 401 usually means “you need credentials.” In this case, the credentials were not the issue. The domain verification was.

The project and Pages access were already set to public. GitLab simply refuses to serve unverified custom domains without authentication. The 401 was GitLab’s way of saying “prove you own this domain.”


The GitLab API Verification Rabbit Hole

I thought I could automate my way out with the GitLab API. I was wrong.

First, I checked the domain with glab:

glab api projects/nurazhar%2Fhomepage/pages/domains/nurazhar.com

It returned verified: false and a verification code. I added the TXT record to Cloudflare, confirmed it propagated with dig, and expected GitLab to pick it up. It did not.

Next, I tried the documented verify endpoint:

glab api --method POST projects/nurazhar%2Fhomepage/pages/domains/nurazhar.com/verify

404 Not Found. The endpoint either does not exist on GitLab.com or requires different parameters than the docs suggest.

Then I tried updating the domain with PUT:

glab api --method PUT projects/nurazhar%2Fhomepage/pages/domains/nurazhar.com \
  --field 'auto_ssl_enabled=true'

Still verified: false. I waited. I queried again. Still false. The API does not trigger a verification check.

The only API action that reliably forced GitLab to look at the TXT record was delete and re-add. That generated a new verification code, which then had to be copied back into Cloudflare. It is a loop, not a fix.

The real fix is the UI button

GitLab → nurazhar/homepage → Settings → Pages → nurazhar.com → “Verify” / “Retry verification”

That button does what the API cannot: trigger GitLab’s verification checker against the current DNS records. The API is great for reading state, but for this specific step, the UI is the source of truth.


The Fix Was Two Commands and One DNS Record

Once the domain was deleted and re-added in GitLab, the verification code changed. I updated the TXT record in Cloudflare and clicked Verify in GitLab.

Record Type Name Value
TXT _gitlab-pages gitlab-pages-verification-code=<code>

After the DNS propagated, GitLab verified the domain and the blog started serving normally. The default GitLab Pages URL never broke — only the custom domain did. That made the diagnosis harder because https://homepage-ba21fc.gitlab.io returned 200 OK the entire time.


Lessons I Actually Need to Remember

Custom domains are state across two systems. Your DNS provider and your Pages host each keep half the truth. When you migrate DNS, you are migrating a contract, not just records.

Verification codes are not static. Deleting and re-adding a domain in GitLab Pages generates a new verification code. Keep the domain and the TXT record in sync.

Always test from an incognito window. My browser was authenticated with GitLab, so the blog loaded. Every public visitor saw a wall.

GitHub README links are cheap uptime monitors. If I had not updated my profile, I might have stayed blind for weeks.

The GitLab API cannot verify a Pages domain. Read state, update auto-SSL, delete, or re-add — but the actual verification button lives in the UI.


A One-Minute Prevention Checklist

Step Check
Before migration Export all DNS records from the old provider
During migration Copy A, AAAA, CNAME, MX, and TXT records
After migration Query each TXT record with dig TXT _record.host
After migration Verify custom domains in GitLab / GitHub / Vercel
If the API says unverified Click “Retry verification” in the GitLab UI
Ongoing Treat README links as uptime monitors and check them monthly

The Resume Angle

This is exactly the kind of incident a hiring manager wants to hear about: a methodical infrastructure debugging story. DNS migration, custom domain verification, GitLab Pages auth behavior, cross-provider state, API exploration, and public verification through curl and browser tests. It is not a flashy bug, but it is a real one that affects real users.


DNS migrations are 90% copy-paste, 10% the one record you forgot to copy, and 100% solved faster by the UI button than by the API.