Zimbra configuration
Use this page when mail is not being processed by MSH Zimbra Rules even though the services are running. All zmprov and postconf commands below run on the Zimbra server as the zimbra user (sudo su - zimbra).
1. Verify the milter is registered
Check the values stored in Zimbra's server attributes:
zmprov gs $(zmhostname) zimbraMtaSmtpdMilters zimbraMtaNonSmtpdMilters zimbraMtaMilterDefaultAction
Then check what Postfix is actually running with:
postconf smtpd_milters non_smtpd_milters milter_default_action
Expected output:
smtpd_milters = inet:localhost:7080
non_smtpd_milters = inet:localhost:7080
milter_default_action = accept
If zmprov gs shows the values but postconf does not, the MTA has not picked up the change yet:
zmmtactl reload
If both are empty, register the milter as described in Zimbra configuration.
Never add the milter by editing Zimbra's main.cf directly. Zimbra regenerates main.cf on every zmmtactl restart or zmmtactl reload, so such changes silently disappear - which is a common reason a previously working milter "stops" after an MTA restart.
2. Check for conflicting milter configuration
If Zimbra's own milter is enabled, it also populates smtpd_milters. Check it:
zmprov gs $(zmhostname) zimbraMilterServerEnabled
If it reports TRUE, zimbraMtaSmtpdMilters (or postfix_smtpd_milters on older versions using zmlocalconfig) must be a list containing both sockets, e.g. inet:localhost:7026 inet:localhost:7080. Make sure the same milter is not configured twice.
3. Verify the milter is reachable from the MTA
Check that the milter service is running and listening on its port (default 7080):
systemctl status msh-zr-milter.service
sudo ss -tlnp | grep 7080
If the milter address registered in Zimbra uses a different host or port than the milter actually listens on (for example after changing MILTER_PORT in etc/config.cf), the MTA cannot connect.
4. Test the mail flow
Send a test message through the system, for example to one of your own mailboxes. Then check both sides:
- On the Zimbra side, follow the MTA log while the message is delivered and look for milter-related warnings (
milter,connect to Milter serviceand similar):
tail -f /var/log/zimbra.log
- On the MSH Zimbra Rules side, the milter logs every processed message. Watch the application log while sending the test message:
journalctl -u msh-zr-milter.service -f
Processed messages also appear in the Events History page of the web admin UI when diagnostic logging is enabled, and the milter adds an X-MSH-Id header to processed messages - inspect the headers of the received test message to confirm it passed through the milter.
5. Mail is deferred when the milter is down
If mail queues up whenever the milter service is stopped, milter_default_action is not set to accept. Set it so mail keeps flowing when the milter is unavailable:
zmprov ms $(zmhostname) zimbraMtaMilterDefaultAction accept
zmmtactl reload
Use tempfail instead only if you deliberately want mail held while the milter is down.