Mastodon instances that fail to communicate with each other often show a “TLS handshake failed” error in the server logs or in the admin dashboard. This error prevents your instance from receiving posts from remote servers and stops your users from following accounts on other instances. The root cause is almost always a misconfigured TLS certificate, an outdated system library, or a firewall blocking the required ports. This article explains why the TLS handshake fails between Mastodon instances and provides step-by-step fixes for the three most common causes.
Key Takeaways: Fixing TLS Handshake Failures in Mastodon Federation
- Administration > Federation > Domain blocks: Check if the remote domain is inadvertently blocked, which can cause connection drops that look like TLS errors.
- Let’s Encrypt certificate renewal: A missing or expired intermediate certificate is the single most common cause of TLS handshake failures between Mastodon instances.
- System package update (openssl, ca-certificates): Outdated TLS libraries on the server prevent negotiation of modern cipher suites required by other instances.
Why TLS Handshake Fails Between Mastodon Instances
Mastodon uses the ActivityPub protocol to exchange messages between instances. Every federation request starts with a TLS handshake over HTTPS. If that handshake fails, the sending instance logs a “TLS handshake failed” error and does not deliver the message.
The handshake can fail for three main reasons:
Expired or Invalid TLS Certificate
Your instance’s TLS certificate must be valid, unexpired, and trusted by the remote instance. If you use Let’s Encrypt, the certificate auto-renews every 60 days. However, if the renewal process fails because the ACME client cannot reach the validation server, the certificate expires and federation breaks. A missing intermediate certificate also causes handshake failures because the remote instance cannot build a complete trust chain.
Outdated OpenSSL or ca-certificates Package
Mastodon instances that run on older operating systems may have OpenSSL 1.0.2 or earlier. Many modern instances require TLS 1.2 or TLS 1.3. If your server only supports TLS 1.0 or TLS 1.1, the handshake negotiation fails. The ca-certificates package must also be current so that your server trusts modern certificate authorities.
Firewall or Reverse Proxy Misconfiguration
A firewall that blocks outbound TCP port 443 prevents your instance from reaching remote servers. Similarly, a reverse proxy like Nginx that terminates TLS incorrectly may send incomplete certificate chains. The error message in the Mastodon logs often says “connection refused” or “timeout” when the real problem is a firewall rule.
Steps to Diagnose and Fix TLS Handshake Errors
Perform these steps in order. Test federation after each step to avoid restarting services unnecessarily.
- Check the Mastodon federation log for the exact error
Open a terminal on your Mastodon server. Runtail -f /home/mastodon/live/log/production.log | grep -i "tls". Look for lines that contain “TLS handshake failed” and note the remote domain name. This tells you which instance is failing to connect. - Verify your own TLS certificate with an external tool
Use the SSL Labs Server Test at ssllabs.com/ssltest. Enter your Mastodon domain. Wait for the scan to complete. Check for these problems: certificate expired, missing intermediate certificate, or weak cipher support. If the grade is lower than B, fix the certificate chain first. - Renew the Let’s Encrypt certificate manually
If the certificate is expired or missing intermediates, runsudo certbot renew --force-renewal --post-hook "systemctl reload nginx". Then verify the new certificate withsudo openssl x509 -in /etc/letsencrypt/live/yourdomain/fullchain.pem -text -noout | grep "Subject:". Ensure the fullchain.pem file contains both your server certificate and the intermediate certificate. - Update OpenSSL and ca-certificates packages
On Ubuntu or Debian, runsudo apt update && sudo apt upgrade openssl ca-certificates -y. On CentOS or Fedora, runsudo yum update openssl ca-certificates -y. Reboot the server or restart Mastodon withsystemctl restart mastodon-web mastodon-sidekiq mastodon-streaming. - Test outbound TLS connectivity to a remote instance
Use the openssl command to simulate a handshake:openssl s_client -connect remoteinstance.social:443 -servername remoteinstance.social. If the output shows “CONNECTED” and a certificate chain, TLS is working. If it shows “connect: Connection refused”, a firewall is blocking port 443 outbound. - Check firewall rules on your server
Runsudo iptables -L -n | grep 443to see outbound rules. If you use ufw, runsudo ufw status. Ensure outbound TCP port 443 is allowed. If you use a cloud firewall like AWS Security Groups or DigitalOcean Cloud Firewall, check that outbound HTTPS traffic is not restricted. - Restart Mastodon and test federation
After applying any fix, restart all Mastodon services:systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming. Then try to follow a test account on a known working instance like mastodon.social. Check the logs again for TLS errors.
If Mastodon Still Has TLS Handshake Errors
Certificate Chain Not Sent by Nginx Reverse Proxy
If your Nginx configuration does not include the full certificate chain, remote instances see only the leaf certificate and reject the handshake. Open your Nginx site config at /etc/nginx/sites-available/yourdomain. Verify that the ssl_certificate directive points to the fullchain.pem file, not to cert.pem. The correct line is ssl_certificate /etc/letsencrypt/live/yourdomain/fullchain.pem;. After editing, run sudo nginx -t and then sudo systemctl reload nginx.
Outdated TLS Version in Nginx
Some administrators disable older TLS versions in Nginx but accidentally also disable TLS 1.2. Check the ssl_protocols line in your Nginx config. It should read ssl_protocols TLSv1.2 TLSv1.3;. If it only lists TLSv1.3, some remote instances that do not support TLS 1.3 will fail the handshake. Add TLSv1.2 back and reload Nginx.
DNS Resolution Failure Masquerading as TLS Error
If your server cannot resolve the remote instance’s domain name, the TLS handshake never starts. Run dig remoteinstance.social on your Mastodon server. If the answer section is empty or shows SERVFAIL, your DNS resolver is broken. Edit /etc/resolv.conf to use a public resolver like 1.1.1.1 or 8.8.8.8. Then test federation again.
TLS Handshake Failure vs Other Federation Errors
| Item | TLS Handshake Failed | Connection Timeout |
|---|---|---|
| Description | SSL/TLS negotiation fails during the handshake | Remote server does not respond within the timeout window |
| Root cause | Expired certificate, missing intermediate, outdated OpenSSL, firewall blocking port 443 | Remote server down, network congestion, firewall dropping packets |
| Error in Mastodon logs | “TLS handshake failed” with remote domain | “Connection refused” or “timed out” |
| Fix | Renew certificate, update packages, fix Nginx config, allow outbound 443 | Wait and retry, contact remote admin, check your outbound firewall |
The table above helps you distinguish between a TLS handshake failure and a simple connection timeout. If you see “connection refused” in the logs, the remote instance may be down for maintenance. If you see “TLS handshake failed”, the issue is almost always on your side or on the remote side’s certificate configuration.
You can now diagnose and fix TLS handshake failures that prevent your Mastodon instance from federating with other servers. Start by checking your certificate with SSL Labs, then update your system packages. If the problem persists, verify that your Nginx configuration sends the full certificate chain and that your firewall allows outbound port 443. For ongoing monitoring, set up a cron job that runs certbot renew weekly and sends a notification if renewal fails.