Your question
I noticed in one of my setups that if storage (foundationdb in our setup) is failing, the stalwart server continues to accept connections and does not provide a 5xx at SMTP greeting. This behaviour causes any sender to continue trying this host rather than checking for a backup MX and dropping the message there. As a result we do not control retention times. A cleaner way would be to provide a 5xx at connection or simply refuse the connection. Is there some config we have that manages this behaviour?
Version: v0.16.25
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
No health-check circuit breaker exists for storage backend to gate SMTP greeting. There isn’t a dedicated “reject connection on storage failure” config found. Let’s check docs for connect stage config options (sieve script at connect stage could do this manually).
Stalwart does not automatically fail closed when the backing store (e.g. FoundationDB) is unreachable. There is no built-in “reject connections if storage is down” setting, so by default the server keeps accepting connections and will just error out mid-session.
The only way to get the 4xx/5xx-at-greeting behavior you want is to implement it yourself at the Connect stage using a Sieve script, Milter, or MTA Hook, which run before the greeting/EHLO response is sent and can reject the connection outright. You would need an external health check (of your own storage backend) that these connect-stage filters consult to decide whether to reject. See the Connect stage docs for how to wire up a script or hook at this point: Connect stage | Stalwart
There is no setting that makes Stalwart itself probe storage health and auto-reject connections when it fails.
This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.
Hmm, yes, a sieve script that checks for a local file would be a nice way, kinda similar to /etc/nologin
A flag file works with a connect-stage script (Connect stage | Stalwart). Trusted scripts can call exec, which returns true when the command exits with 0:
require ["reject", "vnd.stalwart.expressions"];
if eval "exec('/usr/bin/test', ['-e', '/etc/stalwart/nologin'])" {
reject "421 4.3.2 Service temporarily unavailable";
}
I’d answer 421 rather than a 5xx. A 421 at the greeting is a temporary failure, so the sending server moves on to your backup MX; a 5xx tells it the message is undeliverable and it bounces. The script forks a process for every incoming connection, though. On a busy MX I’d prefer to have whatever detects the FoundationDB failure close port 25 at the firewall, which gets you the same fallback without touching Stalwart. Nothing in the server ties the greeting to the store’s health automatically today.