Skip to main content
System.Return('/blog')
3 min read

RDS Certificate Subject-Name Mismatch: Binding Let's Encrypt Across All Four Roles

Twingate routed RDS traffic fine — then RD Gateway rejected every session on certificate subject-name mismatch. The fix: win-acme DNS-01 plus one PowerShell script binding all four RDS roles every 60 days.

Twingate carried the packets. The RD Gateway dropped every session anyway: “The server’s certificate subject name does not match the requested hostname.” The tunnel was healthy; the cryptography was not. What follows extracts that fix from the RDS migration case study: the error string, the cause, and the script. Saturday night, tunnel green, everyone staring at a cert error. Not my favourite hour.

What the error said

Clients launching the Tally RemoteApp over the new Twingate path received:

The server's certificate subject name does not match the requested hostname

The tunnel routed TCP to the Windows Server over ports 3389/443 correctly. The rejection happened at the RD Gateway layer, after routing succeeded.

What was actually wrong

RDS expects clients to connect using a public FQDN (e.g. erp.example.com). Twingate routes traffic using internal DNS (e.g. rds-host.example.internal). The Windows self-signed certificate matched neither name the client actually requested. Every routed connection failed the name check.

Buying a premium certificate would not have fixed the shape of the problem: the internal routing name still would not match a public certificate, and users would still be trained to click through warnings.

The pipeline: win-acme plus Cloudflare DNS-01

An automated Let’s Encrypt pipeline using the win-acme CLI with Cloudflare DNS validation:

  1. Created a private DNS A-record resolving to the internal IP.
  2. Configured win-acme to use the Cloudflare API for DNS-01 challenges, bypassing the need for port 80 to be open (zero inbound ports on the corporate firewall makes HTTP-01 a non-starter).
  3. Forced "PrivateKeyExportable": true in the win-acme JSON config, so the renewed PFX can actually be imported by the RDS roles.

Let's Encrypt certificate lifecycle for the RDS deployment

The lifecycle diagram from the case study: issuance through win-acme, DNS-01 via Cloudflare, binding on renewal.

The script that binds all four roles

Generating the certificate was half the battle. RDS requires the certificate bound across four separate roles, and missing one means that role keeps serving the old self-signed cert. The PowerShell script below runs automatically on every 60-day renewal:

# PowerShell script triggered automatically by win-acme upon successful 60-day renewal
Import-Module RemoteDesktopServices
$CertPath = "C:\Certs\erp-internal.pfx"
$Password = ConvertTo-SecureString -String $env:PFX_PASSWORD -AsPlainText -Force

# Bind the Let's Encrypt wildcard certificate to the entire RDS deployment topology
Set-RDCertificate -Role RDRedirector -ImportPath $CertPath -Password $Password -Force
Set-RDCertificate -Role RDPublishing -ImportPath $CertPath -Password $Password -Force
Set-RDCertificate -Role RDWebAccess -ImportPath $CertPath -Password $Password -Force
Set-RDCertificate -Role RDGateway -ImportPath $CertPath -Password $Password -Force

Write-Host "Tally Prime RDS Infrastructure TLS Certificates updated successfully."

One PFX bound to all four RDS roles on every 60-day renewal

Valid Let's Encrypt certificate bound to the RDS Gateway

Verification: the valid Let’s Encrypt certificate bound to the RDS Gateway, checked after each renewal rather than assumed.

Honest limitations

  • Single-connector estate. The case this fix ships in runs one Ubuntu connector VM: a single point of failure the case study’s own retrospective flags. The certificate pipeline does not fix that.
  • No renewal-failure alerting described. The script binds on successful renewal; a failed renewal that leaves the old cert expiring has no documented page path in the case.
  • Example-internal names. erp.example.internal stands in for the real internal FQDN throughout — substitute your own before running anything here.

Search the error string and you find forum threads ending in “just click through the warning.” Thirty minutes of win-acme plus four Set-RDCertificate lines holds for every 60-day cycle after, and the overlay path that created the mismatch is exactly what the RDS migration case and its narrative companion describe: ZTNA changes which hostname the client requests, and RDS validates that name against its bound certificate.

Share this log: Share on X Share on LinkedIn Share on Reddit

Related logs

↑↓ navigate Tab complete Enter open Esc close View all →