I have set up my email server following the ISPMail tutorial with virtual users in postfix + dovecot + sieve. My problem is: the envelop "variable" in sieve does not contain the original recipient.

I have a mail account, let's call it mail@example.org and additional aliases set up for postfix which all deliver to the aforementioned address:

name@example.org -> mail@example.org
@domain.com -> mail@example.org

The latter being an catch-all address.

Postfix calls dovecot with the following config line in master.cfg:

dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${user}@${nexthop} -a ${recipient}

With sieve I want to put all mails received for the catch-all address into a specific folder. My sieve code looks like this:

if envelope :is :domain "To" "domain.com" {
  fileinto "special-folder";

This sadly does not work. Digging further I found out that what's inside envelop always is the final delivery address, i.e. mail@example.org in this case. I found this using the following rule:

if envelope :matches "To" "*" {
  fileinto "${1}";

And the sieve log telling me:

failed to store into mailbox 'mail@example.org': Mailbox doesn't exist: mail@example.org.

I'm already guessing that this has to be a problem somewhere between postfix and dovecot as the mail log tells me the following:

Aug 29 10:38:27 *** dovecot: lda(mail@example.org): sieve: msgid=<54003C01.1080704@***>: stored mail into mailbox 'INBOX'
Aug 29 10:38:27 *** dovecot: lda(mail@example.org): Error: sieve: execution of script /var/vmail/example.org/mail/dovecot.sieve failed, but implicit keep was successful (user logfile /var/vmail/example.org/mail/dovecot.sieve.log may reveal additional details)
Aug 29 10:38:27 *** postfix/pipe[12469]: A31A28006B: to=<mail@example.org>, orig_to=<test@domain.com>, relay=dovecot, delay=0.29, delays=0.18/0.01/0/0.1, dsn=2.0.0, status=sent (delivered via dovecot service)

Obviously postfix states the original recipient (test@domain.com) and the mailbox delivered to (mail@example.org) but somehow this information gets lost on the way to dovecot?!


This behavior happened because you add {recipient} macro in dovecot-lda argument. As stated in man pipe, the postfix will replace that macro with final recipient (mail.example.org) instead of not original ones (test@domain.com).

Instead of parsing envelope, you can parsing another header like X-Original-To. This header intended to preserve the original recipient before rewriting or aliasing. To enable this header, edit master.cf so the dovecot line become (notice that flag argument was edited)

dovecot   unix  -       n       n       -       -       pipe
  flags=DROhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${user}@${nexthop} -a ${recipient}

Then your sieve script become

if header :matches "X-Original-To" "*" {
  fileinto "${1}";

A bit complicated but the result is you can have original recipient and its aliases.

  • This sounds good and linking to the pipe manual gave me an even better idea: replacing ${recipient} by ${original_recipient} does just what I need. Hopefully there are no problems with this but after some testing I don't see any. – Artemis Aug 30 '14 at 18:44
  • Good job @Artemis. You should award your self by accepting your own answer. – masegaloeh Aug 31 '14 at 23:10

After some testing (the answer by masegaloeh and the help of a friend provided some useful hints) there are two ways (both seem to work equally good):

  1. Use ${original_recipient} instead of ${recipient}:

    As man pipe tells us "This macro expands to the complete recipient address before any address rewriting or aliasing" so it is the solution to my problem. So the modified command line in master.cf should look like

    dovecot   unix  -       n       n       -       -       pipe
      flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${user}@${nexthop} -a ${original_recipient}
  2. Use a X-Original-To header an tell dovecot to set its envelope to this header field:

    As masegaloeh suggested I add O to the flags telling postfix to add the X-Original-To header. Inside /etc/dovecot/conf.d/15-lda.conf I tell dovecot to use this header for its envelope:

    lda_original_recipient_header = X-Original-To

    As the comment above this config options tells us, we must not use the -a option when calling dovecot-lda via postfix because it overrides this setting. Thus the master.cf looks like:

    dovecot   unix  -       n       n       -       -       pipe
      flags=DORhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${user}@${nexthop}
  • 1
    And what about if using LMTP instead LDA? – sebelk Nov 30 '17 at 16:06
  • I am using mailbox_command instead of the master.cf entry and I had some issues invalid user bounces when trying to swap -a for -d. However, just removing -a worked for me. – Zulan Aug 15 '18 at 22:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.