1394 words
7 minutes

Rebuilding danielmagyar.com: the parts that broke

For about two years danielmagyar.com pointed at a single static page on GitHub Pages. It had my name, a job title, and three links. It was fine in the way that a placeholder is fine.

This is what replacing it actually involved, mostly the parts that didn’t go to plan, because those are the parts worth writing down.

Starting with DNS, not the site#

The obvious first move is to build the site. It’s the wrong one. The site is the easy part; the domain and email underneath it are what everything else depends on, and they’re what you don’t want to touch twice.

So: nameservers from Namecheap to Cloudflare first, site later.

The trap: DNSSEC ordering. If your domain has DNSSEC enabled at the registrar and you point the nameservers somewhere new, the DS record still published at the registry no longer matches what the new nameservers are signing. Validating resolvers don’t fall back gracefully. They return SERVFAIL. Your domain goes dark for a large share of the internet, and you can’t fix it quickly because the DS record has its own TTL to wait out.

The order is non-negotiable:

  1. Disable DNSSEC at the registrar
  2. Wait for the DS record to clear
  3. Change nameservers
  4. Wait for the new zone to go active
  5. Re-enable DNSSEC at the new provider

The misconception: TTLs. Every migration guide tells you to lower your record TTLs before cutting over, and that’s good advice, but it doesn’t do what people think for a nameserver change. Record TTLs govern records. The nameserver delegation is governed by the NS TTL at the TLD registry, which for .com is cached at 48 hours and isn’t yours to change.

For most of two days, some resolvers asked Namecheap and some asked Cloudflare. Nothing broke, and not because of TTLs: both sets of nameservers answered identically. Record parity across the overlap window is the actual safety net. Don’t delete anything at the old provider until you’ve verified the new one.

Email, which is where it got interesting#

The domain had been on Namecheap’s Private Email. The plan was Google Workspace, partly for the mailbox and partly because I wanted an identity provider to wire into AWS later.

Two things went wrong immediately.

Signup was blocked by an account I’d forgotten creating. Workspace refused the address I wanted:

this email address is associated with another Google service

At some point I’d used that address to sign into something Google-adjacent, and Google had quietly created a consumer account around it. You can’t create a managed Workspace account at an address a consumer account already occupies.

The fix isn’t obvious: you add Gmail to the existing consumer account. Doing so permanently changes that account’s primary username to the new @gmail.com address and demotes the original to an alternate.

That matters, because Google’s transfer tooling for conflicting accounts only handles conflicts on a primary address; an alternate simply gets released when you create the managed user. So the awkward-sounding fix is the one that unblocks you.

Everything inside the old account survives. Nothing is lost.

The IMAP migration failed on credentials that looked correct. Google’s data import tool kept rejecting the connection to mail.privateemail.com. The server and port were right. The password wasn’t, because the mailbox password is separate from the Namecheap account password, and I’d only ever reached webmail through the dashboard’s single-sign-on button. I had never set the mailbox password. There was nothing to be wrong.

If you’re migrating off a hosted mailbox and the credentials fail, test them independently at the provider’s own webmail login before assuming the migration tool is at fault. It’s a thirty-second check that isolates the problem completely.

SPF, DKIM and DMARC: the bit nobody explains#

Everyone tells you to set all three. Fewer explain why three exist.

SMTP has no authentication. Anyone who can open a socket to a mail server can claim to be sending from your domain. The three protocols each close a different gap:

SPF answers “is this IP allowed to send for this domain?” It’s a DNS record listing authorized senders.

The subtlety: SPF validates the envelope sender (the MAIL FROM that becomes Return-Path), not the From: header a human reads. Those are different fields and frequently different values. SPF alone does nothing to stop someone spoofing your visible address. It also breaks on forwarding, since the forwarding server’s IP isn’t on your list.

DKIM answers “was this signed by the domain, and is it unaltered?” The sending server signs a hash of selected headers plus the body with a private key; the public key lives in DNS under a selector. Because the signature travels with the message rather than depending on the connecting IP, DKIM survives forwarding, unless a mailing list rewrites the subject or appends a footer, which invalidates it.

DMARC ties them together with the concept that makes them useful: alignment. It requires that at least one of SPF or DKIM both passes and matches the domain in the visible From: header. That’s the check that finally protects the address people actually see, and it’s the reason neither of the other two is sufficient alone.

Start DMARC at p=none with an aggregate reporting address. It changes nothing about delivery. It just tells you which senders are using your domain, including the ones you forgot about. Thirty clean days later you move to quarantine, then reject. Jumping straight to enforcement is how people discover their invoicing tool was sending as them, in the worst possible way.

The registrar transfer I nearly got wrong#

I had planned to move the registration to Cloudflare at the November renewal, on the assumption that transferring earlier would waste the time I’d already paid for.

That’s backwards. A transfer adds a year to the existing expiry, so you lose nothing by doing it early.

Waiting is what actually costs you: if the old registrar’s auto-renewal fires first, the registry still adds the transfer year on top, but the old registrar is the one who gets refunded the auto-renewal charge, not you, unless it chooses to pass that back. ICANN’s own advisory on this says registrars aren’t required to, and most don’t ask first.

Transfer inside that 45-day window and you can end up paying two registrars for one extra year of registration.

The right time to transfer is as soon as the new provider is authoritative for DNS.

The site itself#

Astro, built on the Fuwari theme and restyled until it stopped looking like a template.

Static output: no server, no database, nothing to keep patched.

The hosting went through some of its own trouble. It’s now S3 behind CloudFront, provisioned with Terraform: a private bucket with no public access, reached only through CloudFront’s Origin Access Control. The certificate has to be issued in us-east-1, which is a CloudFront requirement rather than a preference, and it validates through a DNS record at Cloudflare the same way the mail records above proved ownership.

Two things needed fixing before it worked properly.

The 403: with Origin Access Control and no list permission on the bucket, S3 can’t distinguish a missing object from an unauthorized listing request, so it answers both with a 403, not a 404. CloudFront needs an explicit rule mapping that 403 to the same error page, or the plan output looks clean while the live site serves the wrong status code.

The leftovers: the apex still carried DNS records from the old GitHub Pages placeholder, which had to be found and cleared before the new ones could go in. Easy to miss if you assume DNS above an unchanged site is also unchanged.

Same rule as the mail records: one entry per resource, never a whole-zone import that would put unrelated records like DKIM keys under a tool that has no reason to know they exist.

Deploy is manual right now: one command builds the site, syncs it to the bucket, and invalidates the CloudFront cache. Wiring that into CI with short-lived credentials is next.

What I’d tell myself at the start#

Do the infrastructure before the interesting part. DNS, email and identity are unglamorous, they’re what everything else sits on, and they’re the things you genuinely don’t want to migrate twice.

And write down the failures while they’re fresh. The DNS and email problems above cost me maybe three hours combined, and every one of them is the kind of thing you’d otherwise solve, forget, and solve again next year.

The site is live. There will be more here: mostly Bedrock architecture, LLMOps, and the question of where AI workloads are legally allowed to run. More on what that work actually looks like is on the about page.

Rebuilding danielmagyar.com: the parts that broke
https://danielmagyar.com/posts/rebuilding-danielmagyar-com/
Author
Daniel Magyar
Published at
2026-08-17
License
CC BY-NC-SA 4.0