We needed a Let's Encrypt certificate for avatar.al-engr.com. DNS-01 challenge. One TXT record. Should have taken five minutes.

It took longer than that.

Why We Needed the Cert

The Cisco Desk Pro has an embedded Chromium browser. We're running a web app on it that needs camera access — getUserMedia. Chromium will not call getUserMedia on an HTTP origin. It requires HTTPS with a valid, trusted certificate.

The Desk Pro has its own certificate trust store, separate from the device's CA store. This is Cisco's way of saying "you can have a cert, but only if we approve it." Enterprise networking is a series of these moments: every layer of abstraction has its own set of requirements that don't quite align with the layer above or below it.

So: Let's Encrypt. DNS-01 challenge. Add a TXT record to prove domain ownership. Get the cert. Move on.

The UI Bug

Frustrated man crying at GoDaddy's DNS interface

The record we needed to add had the name _acme-challenge.avatar. Note the leading underscore. That's not optional — that's how DNS-01 challenges work. ACME protocol, RFC 8555, the underscore is part of the spec.

GoDaddy's DNS management UI rejected it.

"Record data is invalid."

No further detail. No explanation of what, specifically, it found objectionable. Just a red banner and a broken flow.

This is a known GoDaddy bug. Their web UI fails validation on TXT records where the Name field contains an underscore, on certain account types. The underscore is perfectly valid DNS. The issue is client-side form validation that doesn't match RFC 1035. GoDaddy has known about this for years. The fix apparently hasn't made it to all account configurations.

The workaround the internet suggests is to try a different browser, clear your cache, or wait and try again. None of that worked here either, because the bug isn't a rendering glitch — it's the validation logic itself.

One curl Command

GoDaddy has an API. It does not have this bug.

curl -X PUT "https://api.godaddy.com/v1/domains/al-engr.com/records/TXT/_acme-challenge.avatar" \
  -H "Authorization: sso-key YOUR_KEY:YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '[{"data":"your-acme-challenge-token","ttl":600}]'

That's it. Ran it. Record appeared in DNS within seconds. Let's Encrypt verified the challenge. Cert issued. avatar.al-engr.com is now HTTPS with a valid cert that the Desk Pro trusts.

The API accepted a record name with an underscore without complaint, because underscores in DNS record names are valid and the API knows that.

Relaxed man with coffee after fixing DNS via API

Milo Now Owns DNS

After that experience, handing DNS management back to the GoDaddy UI seemed like a bad idea. The UI is unpredictable in ways that matter at inconvenient times — specifically, when you're in the middle of a cert issuance flow and the ACME challenge has a short window.

So we're done with the UI. Milo manages al-engr.com DNS via the GoDaddy API going forward. New records, updates, deletions — all API, all logged, all auditable. No more clicking through a dashboard that may or may not accept what you type depending on factors GoDaddy hasn't documented.

Your API key lives in ~/.env. Milo knows where that is.

The Actual Problem Stack

To recap the chain of absurdity that led here:

  1. Cisco Desk Pro embedded browser requires HTTPS for camera access.
  2. Desk Pro has its own cert trust store — device CA trust doesn't carry over.
  3. So we need a real cert, not a self-signed one.
  4. Let's Encrypt DNS-01 challenge requires a TXT record with an underscore in the name.
  5. GoDaddy's web UI rejects underscore record names on certain accounts.
  6. GoDaddy's API doesn't have this problem.

None of these are hard problems individually. They're just stacked in a way that makes each one a prerequisite for discovering the next.

The cert works. The Desk Pro trusts it. getUserMedia returns a stream. Milo handles DNS now. That's the full story.