TL;DR
- I enabled Bot Fight Mode on
tophhie.cloudandtophhie.devon Saturday 20th June 2026 at 22:09. - Two days later Tophhie Social went dark behind a steady HTTP 525 (Cloudflare <-> origin TLS handshake failure).
- The certificate was valid and on disk. The backend was healthy. The TLS-check endpoint returned 200 to every manual test. Everything lied.
- Root cause: Caddy's on-demand TLS asks a Tophhie Cloud endpoint (
api.tophhie.dev/pds/tls-check) mid-handshake to decide whether to serve a cert. Caddy's Go HTTP client looked like a bot to Bot Fight Mode, got blocked, theGetCertificatecallback threw, and the handshake died withtlsv1 alert internal error. - Fix: disable Bot Fight Mode for the
tophhie.devandtophhie.clouddomains.
---
The setup
Tophhie Social runs on a self-hosted AT Protocol PDS — the same bluesky-social/pds image that backs Bluesky. In front of it sits Caddy, doing TLS termination and reverse-proxying to the PDS on localhost:3000, with a gatekeeper service in the middle for sensitive XRPC endpoints.
The interesting bit is the TLS. Because every account on a PDS gets its own handle subdomain (alice.tophhie.social, bob.tophhie.social, and so on), I can't pre-provision certificates for names that don't exist yet. So Caddy uses on-demand TLS: it issues a certificate the first time it sees a handshake for a given hostname. To avoid becoming an open certificate vending machine, on-demand TLS calls an
