Skip to content
ssldays

Guide

Fly.io TLS certificate expired

Fly.io custom domain TLS fails when certificate issuance stalls or DNS no longer validates. Use fly certs commands, fix ACME DNS records, and verify the app presents a fresh certificate on public hostnames.

Updated May 16, 2026 810 words

A fly.io ssl certificate expired incident means fly certs still lists an overdue certificate or traffic left Fly's managed ACME path—not that your Machines are down.

Teams on Fly.io attach custom domains to apps; Fly's proxy obtains and renews Let's Encrypt certificates when _acme-challenge and app allocation DNS are correct.

CLI messages like Certificate not issued or browsers showing expired dates often follow DNS edits, deleted apps, or hostname moves between organizations.

Use fly certs check and external openssl on the same hostname before redeploying containers.

First response

Install or update flyctl, then:

fly certs list -a APPNAME
fly certs check HOSTNAME -a APPNAME

Note Issued vs Awaiting configuration states. Export openssl notAfter for HOSTNAME from outside Fly's network.

If you recently moved DNS to another provider, Fly cannot renew until challenges resolve again.

Confirm organization and app names before fly certs operations on production. Export fly certs show JSON into tickets. Verify whether IPv6 records send traffic away from Fly while certificates remain on Fly hostnames. Ask whether a recent marketing domain move dropped TXT records at the old DNS host before declaring platform regression.

What this error means

Fly terminates TLS on its Anycast edge for allocated hostnames. Certificate lifecycle is API-driven; you do not SSH in to swap PEM files on a single box.

Expired certificates imply Fly is not the active issuer for that name—common when DNS no longer points to Fly or the hostname was removed from the app but marketing still advertises it.

Internal .internal names and WireGuard paths are separate from public storefront TLS—do not conflate test errors with customer-facing domains.

Public Fly TLS is API-driven ACME at the edge. Operators do not install PEM files on Machines for standard custom domains. Expiry implies DNS trust failure or hostname removal, not container image age. Internal routing mistakes can send testers to legacy DNS while fly certs still lists the hostname as awaiting records.

Common causes

Missing _acme-challenge TXT after switching DNS hosts.

IPv6/AAAA records sending users to non-Fly targets while certs remain on Fly.

Certificate retained on deleted app and re-created without removing stale DNS.

Multiple organizations claiming the same hostname.

Paused or scaled-to-zero apps combined with removed cert renewal (rare; still verify DNS).

Agencies sometimes lose TXT records during registrar migrations. Legacy hostname remains in marketing PDFs after app rename.

Confirm from the outside

OpenSSL

echo | openssl s_client -connect HOST:443 -servername HOST 2>/dev/null | openssl x509 -noout -dates -subject -issuer

Replace HOST with the public hostname users type.

How to read the output

Leaf issuer should be a public CA once Fly completes issuance. Compare serial with fly certs show fingerprint metadata when available.

curl

curl -vI --connect-timeout 10 https://HOST/ 2>&1 | grep -Ei 'expire|SSL certificate|subject:|issuer:'

flyctl issuance

fly certs add HOSTNAME -a APPNAME
fly certs show HOSTNAME -a APPNAME

Follow printed DNS records exactly; wait for check to return ready before closing incidents.

Poll fly certs check every few minutes after DNS edits; Fly edges converge asynchronously. Save fly certs show output alongside openssl serial numbers so platform support can correlate issuance delays with DNS TTL without another reproduction call.

Fix checklist

  1. fly certs add or refresh DNS instructions for the hostname.
  2. Publish _acme-challenge and app CNAME/AAAA as documented.
  3. fly certs check until valid.
  4. Deploy only if routing changed—not required for every SSL fix.
  5. Test HTTP→HTTPS redirects on the custom domain.
  6. Update third-party webhooks to the working hostname.
  7. Monitor all production hostnames on Fly and any legacy origin.
  8. Document DNS owner and Fly org for audits.

Roll out and verify

Fly certificate changes propagate across Anycast edges asynchronously. After fly certs check reports success, wait one propagation interval before closing customer-facing incidents—openssl from two countries reduces false negatives.

If you run multiple apps in one org, audit fly certs list output quarterly. Hostnames removed from apps but left in DNS at a partner agency are a common source of surprise expiry on marketing landing pages.

WireGuard and internal networking tests should not replace public openssl on the branded domain. Incident bridges often confuse internal mesh TLS with customer TLS.

Capture fly certs show JSON in the ticket when escalating to Fly support; include DNS provider screenshots with TTL values.

Update CI smoke tests to hit custom domains, not only fly.dev defaults. Document DNS owners for client domains. Re-run fly certs check from CI after DNS merges to catch TXT drift early in the release cycle.

Include application name and organization in status pages because customers search social media, not internal codenames. Fly machines may scale to zero while certificates remain issued, which confuses teams who conflate health checks with TLS validity—openssl remains authoritative. Corporate DNS filters sometimes block TXT visibility for split-horizon enterprises; validate _acme-challenge from consumer resolvers your customers use. If you front Fly with Cloudflare, understand whether TLS is terminated twice; expired errors at browsers may indicate Cloudflare-to-origin issues while fly certs still list valid. Rotate API tokens used for fly certs automation after incidents so contractors do not leave lingering DNS rights. Document apex redirects separately from cert status because marketing redirects can send users to hostnames not listed in fly certs output. Post-deploy hooks that rewrite DNS without updating fly certs entries recreate this incident class quickly. Teach support staff to collect fly certs check output before escalating to infrastructure because many tickets resolve once a single TXT record is corrected. Capacity planning meetings sometimes schedule DNS cuts without updating fly certs lists; add a gate that requires fly certs check green before go-live approvals. Observability stacks scraping Fly ingress metrics over https need the same hostname fixes as browsers. Train deployers that scaling machine counts is unrelated to certificate trust, preventing wasted rollbacks during high-traffic holidays. Game-day exercises should include a fly certs drill because TXT records are easy to break during registrar migrations. Partners white-labeling your Fly-hosted API need explicit notice when certificate issuers rotate intermediates. List custom domains on executive status dashboards because TLS failures look like latency regressions until openssl clarifies the root cause.

Escalations should bundle fly certs list output, dig for application CNAME and challenge TXT, and openssl notAfter on the customer hostname in one PDF so Fly support engineers do not need live screen sharing to reproduce stale trust. When multiple engineers paste conflicting openssl results, suspect split DNS between corporate VPN and public resolvers before reopening closed incidents.

When to use automation

Certificate files on disk and green panels lie until a stranger's TLS handshake succeeds. Schedule live checks on the exact hostname shoppers or API clients resolve, including redirects and the certificate presented after your platform edge terminates the connection. Pair TLS notAfter with RDAP domain registration data so revalidation is not blocked by registrar billing.

Run a one-shot proof on /check, then add the production hostname to monitoring with alerts at 30, 14, 7, and 1 day thresholds. ssldays reads the live chain external users see—useful when shared hosting, PaaS edges, or CMS layers each claim TLS is fine.

Frequently asked questions

Internal .internal names?

Separate from public custom domain certificates.

Cert stuck awaiting configuration?

DNS records missing or wrong TXT for ACME.

Multiple regions?

Certs are org-wide; DNS is the usual failure point.

Custom IP?

Still validate via fly certs commands and openssl externally.

See what the server presents right now

Free live certificate check — no signup.