Overview
Warden utilizes a Dovecot IMAP Sieve filter to train SpamAssassin when users classify messages as spam or ham (legitimate email) via their email client or webmail interface. Marking a message as spam trains the classifier using the sa-learn binary, while marking it as ham trains it as legitimate mail. All training activity is logged and displayed in the Anti-spam - Learning Statistics dashboard widget.
Monitoring Training Activity
By default, Bayesian filtering rules activate automatically after 200 spam and ham messages have been trained. You can monitor the number of trained items via the Dashboard or by navigating to Reports > Anti-spam - Learning Statistics. All Bayes and Txrep data is stored within the Warden database to optimize maintenance and system performance.
When a user marks a message as spam or ham, the corresponding counter in the Anti-spam - Learning Statistics widget will increment accordingly.

Troubleshooting
If learning statistics are not updating correctly, follow these diagnostic steps:
- Re-run the Application Setup Wizard
Navigate to Settings > Application Setup and complete the setup wizard again. This process re-establishes database connection parameters in /etc/mail/spamassassin/local.cf, which are required for real-time learning functionality.

- Verify SpamAssassin Configuration
The Dovecot learning Sieve filter requires a fully functional SpamAssassin installation and sa-learn binary. Validate the configuration by executing the following command. A successful run will return no errors:
spamassassin --lint
Enable Dovecot Debug Mode
To inspect Sieve filter execution, enable debug logging in Dovecot:
- Open the configuration file located at /etc/dovecot/dovecot.conf.
- Locate the mail_debug parameter and set it to yes:
mail_debug = yes
Restart the Dovecot service to apply changes:
systemctl restart dovecot
Review Mail Logs
With debug mode enabled, monitor /var/log/maillog when a user marks a message as spam. Successful execution will produce output similar to the following:
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: Mailbox INBOX.Spam: Mailbox opened because: UID move
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: imapsieve: mailbox INBOX.Spam: MOVE event
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: imapsieve: Matched static mailbox rule [1]
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: file storage: Using Sieve script path: /var/qmail/popuser/warden-learn-spam.sieve
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: file storage: script: Opened script `warden-learn-spam' from `/var/qmail/popuser/warden-learn-spam.sieve'
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: Opening script 1 of 1 from `/var/qmail/popuser/warden-learn-spam.sieve'
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: Loading script /var/qmail/popuser/warden-learn-spam.sieve
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: Script binary /var/qmail/popuser/warden-learn-spam.svbin successfully loaded
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: binary /var/qmail/popuser/warden-learn-spam.svbin: save: not saving binary, because it is already stored
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: Executing script from `/var/qmail/popuser/warden-learn-spam.svbin'
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: Started running script `/var/qmail/popuser/warden-learn-spam.svbin'
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: Finished running script `/var/qmail/popuser/warden-learn-spam.svbin'
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: action pipe: running program: warden-learn-spam.sh
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh: Created
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh: Pass environment: USER=test@example.com
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh: Pass environment: HOME=/var/qmail/mailnames/example.com/test
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh: Pass environment: HOST=localhost.localdomain
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: Mailbox INBOX.Spam: UID 14: Opened mail because: mail stream
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh: Establishing connection
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh: Forked child process
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh (31354): Connected to program
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh (31354): Finished streaming payload to program
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh (31354): Finished input to program
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh (31354): Disconnected
Aug 21 11:20:32 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh (31354): Waiting for program to finish after 6 msecs
Aug 21 11:20:34 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh (31354): Child process ended
Aug 21 11:20:34 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: program exec:/var/qmail/popuser/warden-learn-spam.sh (31354): Destroy
Aug 21 11:20:34 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: uid=14: pipe action: piped message to program `warden-learn-spam.sh'
Aug 21 11:20:34 el7p17 dovecot: service=imap, user=test@example.com, ip=[192.168.1.100]. Debug: sieve: uid=14: left message in mailbox 'INBOX.Spam'