Let Postfix send emails to Dovecot

I hope you haven’t lost your mind yet. If you are unsure how Postfix and Dovecot work together take a moment and go back to the big picture page.

In a previous chapter we made sure that Postfix knows which emails it is allowed to receive. Now what to do with the email? It has to be saved to disk into the mailbox of the mail user who is eagerly waiting for it. You could let Postfix handle that using its built-in mail delivery agent (MDA) called “virtual“. However compared to the capabilities that Dovecot provides like server-based sieve rules or quotas the Postfix delivery agent is pretty basic. We are using Dovecot anyway to provide the IMAP (and optionally POP3) service. So let’s use its delivery agent.

How can we make Postfix hand over the email to Dovecot? There are generally two ways to establish that link.

  1. Using the dovecot-lda (local delivery agent) process. It can process one email at a time. And it starts up a new process for every email. This was for long the default way. But you can imagine that it does not scale well.
  2. The better option is to use LMTP (local mail transport protocol) that was conceived for this purpose. It can handle multiple recipients at the same time and has a permanently running process which provides a better performance than using the LDA. In short LMTP is a variant of SMTP with fewer features. It is meant for email communication between internal services that trust each other.

You guessed it already – we will go for the second option. You installed the dovecot-lmtpd package earlier. So let’s configure things.

Tell Dovecot where to listen for LMTP connections from Postfix

Edit Dovecot’s configuration file that deals with the LMTP daemon – you can find it at /etc/dovecot/conf.d/10-master.conf. Look for the “service lmtp” section and edit it so that it looks like:

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    group = postfix
    mode = 0600
    user = postfix

This makes Dovecot’s lmtp daemon create a UNIX socket at /var/spool/postfix/private/dovecot-lmtp. Just like in the section dealing with setting up Dovecot we make it put a socket into the /var/spool/postfix chroot directory because Postfix is restricted to that directory and cannot access anything outside of it. So from Postfix’s point of view the socket is located at “/private/dovecot-lmtp”.

Restart Dovecot…

systemctl restart dovecot

Check if dovecot accepted that change:

systemctl status dovecot

The output should read “Active: active (running)”.

Tell Postfix to deliver emails to Dovecot using LMTP

This is even easier. The “virtual_transport” in Postfix defines the service to use for delivering emails to the local system. Dovecot has created a socket file and is ready to listen to incoming LMTP connections. We just need to tell Postfix to send emails there:

postconf virtual_transport=lmtp:unix:private/dovecot-lmtp

The syntax looks crazy? It’s actually simple. You just told Postfix to use the LMTP protocol. And that we want to use a UNIX socket on the same system (instead for example a TCP connection). And that the socket file is located at /var/spool/postfix/private/dovecot-lmtp.

(You will find further information on these steps in the Dovecot configuration on Postfix integration.)

Enable server-side mail rules

One of my favorite features of Dovecot are rules for incoming email that are processed on the server. You can sort away your mailing list emails into special folders. You can reject certain senders. Or you can set up vacation auto-responders. No need to have a mail client running – it all happens automatically even when your mail users are not connected.

The open-source standard (RFC 5228) for such rules is called Sieve. Simply put Sieve is a way to manage server-side email rules. A rule consists of conditions and actions. For example if the sender address matches “steve@example.org” you could tell Dovecot to move such emails to your “steve” folder automatically. These rules are stored on the Dovecot server and executed automatically. Whether you connect from your smartphone your laptop or use the webmail access – the rules always work and require no configuration on the client side.

As we use LMTP that’s where we need to tell the lmtp service that we want to use Dovecot’s “sieve” plugin. Edit the file /etc/dovecot/conf.d/20-lmtp.conf and within the “protocol lmtp” section change the “mail_plugins” line to:

mail_plugins = $mail_plugins sieve

Restart Dovecot and you are done:

systemctl restart dovecot

4 thoughts on “Let Postfix send emails to Dovecot”

  1. In case anyone else copies and pastes the lmtp section blindly like I did and gets the error,

    dovecot[26122]: doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-master.conf line 73: Unexpected ‘}’

    That’s because the actual closing to the “service lmtp {” block is well below the end of the unix_listener entry. So if you paste the closing bracket “}” from the example you’ll have two because of the extra one below the commented out inet_listener example. Remove the one after “user = postfix\n}” and it’ll work.

    1. I find it cleaner to add a bracket after “user = postfix” and then comment out the one that is lower in the configuration. the whole thing looks like this then:

      service lmtp {
      unix_listener /var/spool/postfix/private/dovecot-lmtp {
      group = postfix
      mode = 0666
      user = postfix

      # Create inet listener only if you can’t use the above UNIX socket
      #inet_listener lmtp {
      # Avoid making LMTP visible for the entire internet
      #address =
      #port =

      Either way there is an issue with brackets.

  2. Marek Turnovec

    Is there some way with LMTP delivery to get something like “X-Original-To” header for filtering with Sieve? I used this in the past with LDA, because I have different e-mail address and I want to have mails for all of them to end in one IMAP account and there filter them into different folders bellow Inbox according the recipient address…

    1. Davide G. M. Salvetti

      Maybe you could consider plus addresses: route email@domain to user+email@domain with virtual and sieve on :detail.

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top