On Stalwart 0.16.22 Community Edition, how can I confirm from runtime logs or another supported diagnostic that SMTP messages arriving on the smtp listener invoke my DATA-stage Milter (rspamd:11332, enabled by listener == ‘smtp’)? Rspamd and ClamAV scan directly, but SMTP messages are accepted and I see no corresponding Rspamd scan; is there a known issue or a specific setting I should check?
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.
I now have enough to answer. Let me also check how to enable trace logging / tracing config quickly for the milter.io-error, since that’s likely relevant diagnostics (connection issues).
I have sufficient grounding now.
To confirm your milter is actually being invoked and to see why no scan is showing up, enable tracing for the milter event group at trace level (this logs every raw read/write plus every milter action, error, timeout, or disconnect). The relevant events are:
milter.action-accept / milter.action-reject / milter.action-discard / milter.action-temp-fail (info) — confirms the milter returned a verdict
milter.io-error, milter.timeout, milter.disconnected, milter.frame-invalid, milter.unexpected-response (warn) — would explain a silent skip if the connection to rspamd is failing
milter.read / milter.write (trace) — raw protocol traffic, useful to confirm the connection is opened at all
Set up a Tracer object (WebUI: Settings › Logging & Tracing) that captures the milter event group at trace level and watch it while sending a test message through the smtp listener.
Also double-check two configuration points that commonly cause a milter to silently not fire:
The enable expression on your MtaMilter object must evaluate to true for that specific session. If you wrote listener == 'smtp' but your test connection actually landed on a different listener (e.g. submission), the milter will be skipped with no error at all, since enable simply gates whether the milter runs, it doesn’t log a skip event by default.
Make sure "stages" includes "data": true (it is the default, but verify it wasn’t overridden), since a milter enabled only for connect/ehlo/etc. would never reach the DATA phase where rspamd actually scans content.
If tracing shows no milter.* events at all for a session that should have triggered it, that confirms the enable expression (or the listener name itself) is the culprit rather than a scanning issue in rspamd.
This is the same setup as Stalwart 0.16.22 accepts SMTP DATA without a Rspamd Milter scan, and I’ve answered there. In short, with TempFail on Error enabled a 250 means the milter isn’t loaded at all, since a failed connection would have returned a 4xx. Run Reload server settings after saving the MtaMilter and check the result for a hostname resolution error. Once it’s loaded, every message that passes the milter logs milter.action-accept at info level.