Expired SSL certificates prevent migration or recovery

Your question

backend unavailable error=backend unavailable: destination temporarily marked down after repeated failures protocol=“imap” destination=legacy

The failures are due to expired certificates supposedly handled by ACME, but it seems that ACME is backing off from renewal because it tries to request too many certificates in a too short time.

I need to unlock this certificate issue in order to resume normal email operations, and to pursue migration. But there does not seem to be a “manual override” for this case.

Since HSTS is enabled, webui is not available either.

  1. Legacy service is bound to internal IP so that the proxy can bind to the public IPs
  2. New service is fine, but has no imported accounts yet.
  3. Since legacy services are unavailable due to TLS issues, no migration nor recovery can happen (at least using the web interface)

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

This is very useful, it addresses the recovery admin/HSTS lockout situation. Let me pull that section fully.

Found it. This is the migration proxy’s circuit breaker, and there is a documented way to force it back into service immediately.

Two separate problems are stacked here, and both have documented workarounds:

1. The legacy destination is marked down by the proxy’s health circuit breaker.

When TLS to a backend destination fails repeatedly, the migration proxy’s circuit breaker marks that destination down and rejects new connections for host_down_cooldown before probing again — this is exactly the “destination temporarily marked down” message. You can force it back into service immediately, without waiting for the ACME renewal to catch up, using the management API:

curl -k -H "Authorization: Bearer <token>" \
  -X POST "https://127.0.0.1:9443/destinations/reset?destination=legacy"

Check GET /destinations first to confirm it’s the TLS handshake (not something else) causing the failures. See Destinations and Management API.

2. The underlying cause: the legacy backend’s certificate is genuinely expired, so every reconnect attempt fails TLS verification again.

Since this is an internal backend leg reached only by the proxy, you don’t need a trusted cert there. Either fix the ACME renewal, or as a temporary override set tls_allow_invalid_certs = true (or pin the specific cert with tls_pinned_cert_sha256) on that destination’s config so the proxy stops rejecting the connection on cert grounds while you sort out the certificate itself. Resetting the destination alone won’t help if the cert failure recurs on the very next probe. See Troubleshooting › A backend cannot be reached / TLS negotiation fails.

3. WebUI locked out by HSTS on an expired-cert host.

If the Stalwart admin WebUI itself is unreachable because the browser refuses the expired cert under HSTS, and the HTTP listener has been disabled, start the server with STALWART_RECOVERY_MODE=1, which re-enables the HTTP listener on port 8080 and accepts STALWART_RECOVERY_ADMIN regardless of directory/cert state, letting you sign in and fix the certificate or ACME provider config. Restart normally afterward. See Troubleshooting › HTTPS not yet reachable.

Once ACME renewal succeeds (or you replace the certificate manually as a Certificate object), reset the destination again if it’s still marked down.

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

OK I got somewhere.

OK I figured out the issue: LE had ‘paused’ the domain for a while, which brought the expired certificate situation. Nothing to do with Stalwart, except maybe that ACME failure should be visible in the webui and the unpause link available from there for explanations.

In the logs, you can find a (long) link to portal.letsencrypt.org.