The self-signed rcgen certificate you’re seeing is the fallback certificate Stalwart presents while the ACME challenge is still in progress or has silently failed. After more than a day without a valid Let’s Encrypt certificate, the ACME challenge is almost certainly failing. Here is a systematic checklist to diagnose and fix it:
1. Check which challenge type is configured
The default challenge is TLS-ALPN-01, which requires port 443 to be publicly reachable from Let’s Encrypt’s servers. If your Ubuntu server is behind a firewall, NAT, or a cloud security group that blocks inbound port 443, the challenge will always fail silently and the server will keep showing the self-signed fallback.
Go to the WebUI: Settings › TLS › ACME Providers and check the challengeType field:
TlsAlpn01 (default) – requires port 443 open to the internet
Http01 – requires port 80 open to the internet
Dns01 / DnsPersist01 – no public port required, but needs DNS automation
The most common cause of this issue on a fresh install is that port 443 is not reachable from the internet.
2. Verify your Domain is configured for Automatic certificate management
In the WebUI: Settings › Domains, open your domain and confirm that certificateManagement is set to the Automatic variant and has the acmeProviderId pointing to your ACME provider. If it is set to Manual, ACME will never run.
3. Check ACME event logs
Stalwart emits specific ACME events you can look for in the logs:
acme.auth-start – challenge started
acme.auth-valid – domain validated successfully
acme.auth-error – something went wrong
If you see acme.auth-error events, the error detail will tell you exactly what Let’s Encrypt rejected (usually a connectivity or DNS issue).
4. Test-run against Let’s Encrypt staging first
If you keep retrying against the production Let’s Encrypt directory and hitting failures, you may exhaust rate limits. In the WebUI, temporarily change the AcmeProvider directory to:
https://acme-staging-v02.api.letsencrypt.org/directory
to debug without consuming production rate-limit budget. Switch back once validated.
5. If port 443 is blocked, switch to HTTP-01
If your host can serve HTTP but not TLS directly (e.g., behind a proxy), change challengeType to Http01 – this requires port 80 to be reachable. If neither port is available, use Dns01 with a supported DNS provider.
Relevant docs:
This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.