Sieve is a filtering language for mail servers — standardized, powerful, and built right into Mailcow. As domain admin you can set Sieve filters that apply to all mailboxes of your domain — before the mail lands in the user’s mailbox.
The most common use case: I want all mail from a specific newsletter sender to count as “wanted” domain-wide and not end up in spam, without every user having to set that up themselves.
Important: personal filters that only one user wants for themselves belong in their personal Sieve in webmail. Domain-wide Sieve filters are for rules that affect everyone.
Creating a filter
In the Mailcow GUI:
- Configuration → Filters.
- Click Add.
In the dialog:
| Field | Value |
|---|---|
| Active | enabled |
| Filter type | ”prefilter” or “postfilter” |
| Domain | your domain |
| Sieve script | see below |
| Description | descriptive text |
Prefilter vs. postfilter
- A prefilter runs before the user’s personal filter kicks in. Used e.g. to discard or redirect mail before the user filter sees it.
- A postfilter runs after the personal filter has finished. Used e.g. as a last safety layer to sort mail if the user has no own filter for it.
From our experience: 90% of domain-wide filters are postfilters — they only kick in when the user hasn’t specified anything themselves. You use prefilters when you want to enforce domain policy.
The Sieve language — the most important patterns
Sieve is not a scripting language. You describe conditions and actions, no program flow.
Pattern 1: sorting a newsletter sender into a folder
require ["fileinto", "envelope"];
if anyof (
address :is "from" "newsletter@firma-x.com",
address :contains "from" "@info-newsletter.de"
) {
fileinto "Newsletter";
stop;
}
Mail from these senders automatically lands in the “Newsletter” folder — on every mailbox of your domain.
Careful: the target folder has to exist in every mailbox. If it isn’t there, the mail lands in the INBOX.
Pattern 2: discarding certain senders entirely
require ["envelope"];
if address :is "from" "spam@bekannter-spam.com" {
discard;
stop;
}
Mail from that sender is discarded outright, arrives in no mailbox, and the sender gets no bounce.
Careful: discard is final — no way to get the mail back later. For important senders, prefer fileinto "Spam"; over discard;.
Pattern 3: flagging mail with certain keywords
require ["fileinto", "imap4flags"];
if header :contains "subject" "[Rechnung]" {
fileinto "Rechnungen";
addflag "\\Flagged";
stop;
}
Mail with “[Rechnung]” in the subject is sorted into the “Rechnungen” folder and marked with a flag (star).
Pattern 4: redirecting mail to role addresses
require ["envelope", "redirect"];
if address :is "to" "alt-info@deinverein.de" {
redirect "info@deinverein.de";
stop;
}
Mail to the old address is forwarded to the new one. Similar to an alias — but conditional when needed, with date filters or other conditions.
Pattern 5: rejecting external mail with certain content
require ["body", "reject"];
if anyof (
body :raw :contains "0xDEADBEEF"
) {
reject "Diese Mail wurde aus Sicherheitsgründen abgelehnt.";
stop;
}
Mail with suspicious content is rejected with a bounce message.
The Sieve language — key directives
| Directive | What it does |
|---|---|
require ["..."] | Enables required Sieve extensions. Always goes at the very top. |
if, elsif, else | Conditional logic. |
anyof, allof, not | Boolean combination of multiple conditions. |
address, header, envelope, body | What is matched against. |
:is, :contains, :matches, :regex | How it is matched. |
fileinto "folder" | Move into a subfolder. |
discard | Discard. |
redirect "..." | Forward. |
reject "reason" | Reject with a bounce. |
addflag, setflag | Mark with IMAP flags (Flagged, Seen, Answered). |
stop | Abort the filter, stop processing the mail. |
Full reference: RFC 5228 — but for 95% of use cases, the patterns above are enough.
Testing filters
Once you’ve created a new filter:
- Leave Active set to inactive at first.
- Send a test mail that the filter should catch.
- Enable the filter step by step.
- Test again.
For syntax errors, Mailcow already refuses to save — you get an error message with the line number.
For logic errors (the filter catches the wrong mail), you have to think it through yourself — or open a ticket, we’ll help.
Best practices
Document your filters. Put a descriptive text in every filter’s description field. “Filter 1” says nothing. “Newsletters from info-newsletter.de into folder X” is clear.
Use prefilters sparingly. Prefilters override user decisions — users can’t do anything about it unless you change it. If a user later wants a different sorting and your prefilter stands in the way, they’ll be annoyed. Prefer postfilters that complement user filters.
Be careful with spam patterns. Spam senders change domains and addresses constantly. Domain-wide spam filters often go stale quickly. Better: tune Mailcow’s own spam filter (Rspamd) at the server level — ask us.
Never discard for unknown senders. If you want to discard a sender entirely, be sure nothing important could be among it. Otherwise, prefer fileinto "Verdacht";.
Frequently asked questions
Do domain-wide filters apply to new mailboxes? Yes, automatically. As soon as a mailbox is created in the domain, all active domain filters apply immediately.
Can users see domain-wide filters? No. They only see their personal filters in SOGo. If a user wonders why a mail landed in a certain folder and can’t find a matching filter of their own, it’s probably a domain filter.
How can I test a filter before going live? Mailcow has no built-in Sieve tester. Best practice: save the Sieve in the filter edit (set to “inactive”), then send a test mail to your own mailbox that the filter would catch — and check what happens. Step by step.
Can I have multiple filters in parallel? Yes, as many as you like. They run in the order you set under “order” in the filter edit.
What happens when a filter has an error? Mailcow logs the error in E-Mail → Mail logs. The mail is still delivered — that’s the intended “fail open” behavior, so a broken filter doesn’t paralyze the whole domain.
Can I set Sieve filters per mailbox separately? Domain-wide as domain admin: no. Per-user filters: yes, in SOGo webmail. More in Personal Sieve filters in webmail.
How do I debug a filter that doesn’t kick in?
Add an extra fileinto "Sieve-Debug"; to the Sieve script — a folder where you can see which mails passed through the filter. If the debug folder stays empty, the condition doesn’t match.
What’s next
First login as domain admin in the Mailcow GUI
After ordering your mail server plan, you get access to the Mailcow GUI. Here's an overview of what you see as domain admin and where to find what.
Creating and editing mailboxes, setting quotas
How to create new mail addresses as domain admin, assign storage quotas, change passwords and delete mailboxes again.
Setting up aliases and a catchall
Route several mail addresses into one mailbox — info@, kontakt@, presse@ all in a single inbox. Plus a catchall for every typo address.
Creating app passwords for mail clients
With 2FA active, Outlook, Apple Mail and friends need an app password instead of your main password. How to create them, revoke them and avoid password chaos.