Mercurial refused the connection. The logs pointed straight at TLS.
Mercurial’s TLS configuration is often overlooked, but it defines whether your repositories stay secure or collapse under attack. When Mercurial connects over HTTPS, it relies on the underlying Python ssl library to validate servers and encrypt traffic. Any weak cipher, expired certificate, or misconfigured CA immediately undermines repository integrity.
Start with the basics. Set hostfingerprints in your .hgrc to pin server certificates. This prevents man-in-the-middle attacks when fetching or pushing. Use SHA-256 fingerprints, not MD5 or SHA-1. Example:
[hostfingerprints]
yourserver.com = SHA256:abcdef123456...
Enable strict certificate checks. In [web], set certificate to the correct server cert file. Avoid disabling verifycerts unless debugging. If your Mercurial instance still uses old TLS versions, force an upgrade by configuring Python’s ssl context to require TLS 1.3. Modern ciphers like TLS_AES_256_GCM_SHA384 give strong encryption with minimal overhead.
Mercurial supports client certificates for mutual TLS. In [ui], set clientcert to your .pem file and secure the private key with filesystem permissions. Always match the certificate’s CN or SAN fields to the server name you expect.
To verify your setup, run:
hg clone https://yourserver.com/repo --config ui.traceback=True
Check the output for SSLHandshakeError, mismatched fingerprints, or warnings about deprecated protocols. Fix these immediately—production environments should have 0 TLS warnings.
A hardened Mercurial TLS config is not optional. Attackers with network access can steal code, corrupt commits, or inject malicious changes. Correct configuration blocks them before the handshake completes.
Get your TLS setup right, then automate checking it. See it live in minutes at hoop.dev and keep every hg push secure.