← Back to ProDirt Blog

GoDaddy R1 Root Breaks RD Gateway: Fixing the Untrusted Certificate Chain

A renewed GoDaddy wildcard cert took down Remote Desktop Gateway for a chunk of users — and the certificate itself was completely valid. Here's the Schannel trap and how to fix it on the server.

We renewed a GoDaddy wildcard cert on an RD Gateway, rebound it, and everything looked fine — the cert was valid, not expired, the right name. Then the tickets started: some users couldn't connect. Remote Desktop threw a certificate-not-trusted error, RDWeb wouldn't load cleanly, and it was maddeningly inconsistent — my patched Windows 11 box connected fine, but a coworker on an older thin client got a hard wall.

Same server, same cert, different clients. That's the tell that it's not the certificate — it's the chain.

What Was Actually Happening

GoDaddy has been transitioning its DV TLS certificates to a new root hierarchy: GoDaddy TLS Root CA - R1, a root that was only issued in August 2025. When I dumped the chain the gateway was serving, the top of it was the self-signed R1 root — subject and issuer both GoDaddy TLS Root CA - R1.

That root is barely a year old, so it isn't in older trust stores yet. Anything that hasn't received a recent root-store update has nothing to anchor the chain to and dies at the TLS handshake:

Updated machines already trust R1, so they connect fine — which is exactly why the failure looks random until you line up who's breaking.

ℹ️ Why the server was even offering the self-signed root: Windows Schannel builds the shortest valid chain it can. The self-signed R1 root was sitting in the gateway's own Trusted Root store, so Schannel took the one-hop, self-anchored path to it — a root your old clients don't have — instead of building up to a root they do.

The Fix — On the Gateway, Not the Clients

The fix is the R1-to-G2 cross-signed certificate. It has the subject GoDaddy TLS Root CA - R1 but is issued by Go Daddy Root Certificate Authority - G2 — a root that's been in every trust store since around 2014. Drop that cross-cert into Intermediate Certification Authorities and remove the self-signed R1 root, and Schannel is forced to rebuild the chain so it anchors at G2 instead. It all happens on the server; you touch nothing on the clients.

Run these as administrator on the gateway — all PowerShell.

1. Confirm what the server is chaining to

$b = Get-ChildItem Cert:\LocalMachine\My | ? { $_.Subject -like "*yourdomain.com*" }
$c = New-Object Security.Cryptography.X509Certificates.X509Chain
$c.Build($b) | Out-Null
$c.ChainElements | % { "{0}`n   -> {1}" -f $_.Certificate.Subject, $_.Certificate.Issuer }

If the last element's subject and issuer are both GoDaddy TLS Root CA - R1, that's your broken chain.

2. Pull GoDaddy's intermediate bundle and import it

[Net.ServicePointManager]::SecurityProtocol = 'Tls12'
$p = "$env:TEMP\gd_all_intermediates.p7b"
Invoke-WebRequest "https://certs.godaddy.com/repository/all_intermediate_ca_certificates.p7b" -OutFile $p -UseBasicParsing
certutil -addstore CA $p

3. Verify the R1→G2 cross-cert actually landed

Get-ChildItem Cert:\LocalMachine\CA |
  ? { $_.Subject -like "*GoDaddy TLS Root CA - R1*" } |
  Select Subject, Issuer, Thumbprint, NotAfter | fl

You want one whose Issuer is Go Daddy Root Certificate Authority - G2. If nothing comes back with a G2 issuer, stop — the bundle didn't include it and you'll need the cross-cert directly from the GoDaddy repository.

4. Remove the self-signed R1 root so Schannel stops taking the short path

$s = New-Object Security.Cryptography.X509Certificates.X509Store("Root","LocalMachine")
$s.Open("ReadWrite")
$r = $s.Certificates | ? { $_.Thumbprint -eq "C6FC6A49610C09CB640E250CCB05CDE834660517" }
if ($r) { $s.Remove($r); "Removed R1 root" } else { "Not present" }
$s.Close()

5. Confirm the G2 root is present, then reboot

Get-ChildItem Cert:\LocalMachine\Root |
  ? { $_.Subject -like "*Go Daddy Root Certificate Authority - G2*" } |
  Select Subject, NotAfter

Then reboot. Schannel caches chains aggressively and a TSGateway service restart often isn't enough — mid-outage, the reboot is the reliable move. Re-run step 1 afterward: the chain should now terminate at Go Daddy Root Certificate Authority - G2.

⚠️ It comes back every renewal. Installing a GoDaddy bundle — including on your next cert swap — often re-adds the self-signed R1 root to Trusted Root, which re-breaks the chain even with the cross-cert sitting right there. The removal in step 4 has to run after the cert is bound, followed by a reboot. Fold it into your certificate-deployment checklist as a mandatory step, not a one-time break-fix, until the R1 root is broadly trusted.
ℹ️ One more caveat: GoDaddy also dropped the ClientAuth EKU from these DV certs — the leaf now carries Server Authentication only. That's fine for RD Gateway and RDWeb, but if the same wildcard is bound to anything doing client authentication (mutual TLS, some VPN or RADIUS setups), that will break separately and the cross-cert won't help it.

Why Fix It on the Server Instead of the Clients

You can push the R1 root to clients via GPO or Intune, and it works — but it's the slow path, and it's useless for exactly the devices that break first: thin clients you don't manage that way, and personal phones. Fixing the chain on the gateway repairs every client at once, including the ones you can't touch. One server, done.

Wrapping Up

A "valid" certificate that only some clients trust is almost always a chain problem, not a cert problem. GoDaddy's R1 transition is a textbook case: the server happily serves a brand-new self-signed root that half your fleet has never heard of. Install the R1→G2 cross-cert, evict the self-signed root, reboot, and Schannel anchors where it should — and then remember to do the root eviction again on every renewal until R1 ages into the trust stores.

References: GoDaddy — R1 root hierarchy transition · GoDaddy — Fix an untrusted root or chain error · GoDaddy certificate repository.