Skip to content

Setup Dovecot and Postfix

Dejan Strbac edited this page Nov 12, 2026 · 1 revision

This page sets up ALPS on the same host as Dovecot and Postfix. Dovecot serves IMAP, with METADATA turned on, and ManageSieve through Pigeonhole. Postfix takes submissions on port 587, checks passwords through Dovecot, and hands mail for local users to Dovecot over LMTP. The page gives complete Dovecot files for Dovecot 2.4 (Debian 13) and Dovecot 2.3 (Debian 12, Ubuntu 24.04), the Postfix settings and the ALPS configuration, then shows how to check each part. What ALPS needs from any mail server is on Mail-Server-Requirements.

What you get

  • Users sign in to ALPS with their full address, such as alice@example.com, and the password in Dovecot's user file. ALPS uses the same address and password for IMAP, ManageSieve and SMTP, so there is no separate account for ALPS.
  • ALPS reaches all three services at mail.example.com over TLS and checks the certificate each time: IMAP on port 993 (imaps://), submission on port 587 (smtp://, STARTTLS) and ManageSieve on port 4190 (managesieve://, STARTTLS).
  • Dovecot keeps each account's ALPS records as METADATA in a file in the user's home, such as /var/vmail/example.com/alice/dovecot-attributes. That covers settings, sending addresses (identities), security keys and the OpenPGP keyring. They are still there after a new sign-in and after ALPS restarts.
  • Every account has Drafts, Sent, Trash, Junk and Archive from its first sign-in.
  • Settings > Filters and Settings > Auto-reply edit the user's Sieve script over ManageSieve. Dovecot runs the script when it delivers a message.
  • Postfix lets each login send only from the addresses you list for it. A sending address a user adds in ALPS works once you list it for that login.
  • Mail for example.com, whether a user sent it from ALPS or it arrived on port 25, is delivered to Dovecot over LMTP.
  • Dovecot lists THREAD=REFS, SORT, PREVIEW, MOVE and UIDPLUS, so ALPS shows conversations and message previews. It does not list MULTISEARCH, ACL or QUOTA with this configuration, so ALPS shows no Search All button, no folder sharing and no storage meter (see Mail-Server-Requirements).

This page does not cover spam filtering, DKIM signing, SPF and DMARC records, or the MX record for receiving mail. Calendars and contacts need a CalDAV and CardDAV server, which Dovecot does not provide (see docs/CDAV.md).

The step people miss: METADATA

Turn on METADATA in Dovecot. ALPS has no database. It keeps every account's settings, sending addresses, security keys and OpenPGP keyring on the IMAP server as METADATA. Dovecot offers METADATA only when both of these are set:

  1. imap_metadata = yes for the IMAP protocol, and
  2. a mail attribute dictionary, which is where Dovecot stores the entries.

With either one missing, Dovecot does not list METADATA, and ALPS still signs users in. Settings then seem to save, but they are gone at the next sign-in, and security keys cannot be kept.

Dovecot 2.4:

mail_attribute {
  dict file {
    path = %{home}/dovecot-attributes
  }
}
protocol imap {
  imap_metadata = yes
}

Dovecot 2.3:

mail_attribute_dict = file:%h/dovecot-attributes
protocol imap {
  imap_metadata = yes
}

Both are part of the complete files below. ALPS does not check for METADATA when it starts. Without it, ALPS logs this line once per process and keeps each connection's records in memory only:

alps/provider: IMAP server doesn't support the METADATA extension, using transient store instead

Dovecot lists METADATA only after LOGIN. The capabilities in its greeting do not include it. Check it works shows how to look. Storage-in-IMAP-METADATA describes what ALPS stores.

Before you start

  • A Debian 13 host (Dovecot 2.4), or a Debian 12 or Ubuntu 24.04 host (Dovecot 2.3), with these packages:

    apt install dovecot-imapd dovecot-lmtpd dovecot-managesieved dovecot-sieve postfix

    When Postfix's installer asks for the mail configuration type, choose Internet Site, with mail.example.com as the system mail name.

  • mail.example.com points at this host, and the host can reach itself by that name: getent hosts mail.example.com prints an address of this host. If it cannot, see When mail.example.com does not lead back to this host.

  • A certificate for mail.example.com at /etc/letsencrypt/live/mail.example.com/fullchain.pem and privkey.pem, which is where certbot writes it. ALPS checks the certificate against the host's system roots for IMAP, SMTP and ManageSieve alike, so it must come from a CA those roots trust.

  • ALPS installed as /usr/local/bin/alps and run as user alps by the shipped systemd unit dist/alps.service, as described in Running-in-Production.

  • A reverse proxy serving ALPS at https://webmail.example.com, as on Setup-Behind-a-Reverse-Proxy.

Configuration

Dovecot 2.4 (Debian 13): /etc/dovecot/dovecot.conf

This file replaces the one the Debian package installs. Keep a copy of Debian's first (cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.debian). The new file does not include conf.d/, so nothing in that directory applies any more.

# /etc/dovecot/dovecot.conf for Dovecot 2.4 (Debian 13)
dovecot_config_version = 2.4.0
dovecot_storage_version = 2.4.0

protocols = imap lmtp sieve

# TLS: the certificate for mail.example.com
ssl = required
ssl_server_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_server_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem

# Users: full addresses as logins, in a passwd-file
auth_mechanisms = plain login
passdb passwd-file {
  passwd_file_path = /etc/dovecot/users
}
userdb static {
  fields {
    uid = vmail
    gid = vmail
    home = /var/vmail/%{user | domain}/%{user | username}
  }
}

# Mail storage
mail_driver = maildir
mail_path = ~/Maildir
mail_uid = vmail
mail_gid = vmail

# Folders ALPS files into or offers, created for every account
namespace inbox {
  inbox = yes
  separator = /
  mailbox Drafts {
    special_use = \Drafts
    auto = subscribe
  }
  mailbox Sent {
    special_use = \Sent
    auto = subscribe
  }
  mailbox Trash {
    special_use = \Trash
    auto = subscribe
  }
  mailbox Junk {
    special_use = \Junk
    auto = subscribe
  }
  mailbox Archive {
    special_use = \Archive
    auto = subscribe
  }
}

# METADATA: where ALPS keeps settings, identities, security keys and the
# OpenPGP keyring. Both parts are needed.
mail_attribute {
  dict file {
    path = %{home}/dovecot-attributes
  }
}
protocol imap {
  imap_metadata = yes
  # Every ALPS session connects from this host's address.
  mail_max_userip_connections = 30
}

# Sieve: filters and auto-reply run when LMTP delivers
sieve_script personal {
  driver = file
  path = ~/sieve
  active_path = ~/.dovecot.sieve
}
protocol lmtp {
  mail_plugins {
    sieve = yes
  }
}

service managesieve-login {
  inet_listener sieve {
    port = 4190
  }
}

# Postfix: delivery over LMTP, and SASL for submission
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}

Notes on this file:

  • dovecot_config_version must be the first setting in the file. Dovecot 2.4 does not start otherwise.
  • METADATA is the mail_attribute block together with imap_metadata = yes (see above).
  • mail_max_userip_connections counts one user's IMAP connections from one address, and Dovecot's default is 10. Each ALPS session holds its own connection and, while it has background work, a second one. A user can have up to max_sessions_per_user sessions (10 by default), and every one of them connects from this host's address. That makes up to 20 connections, so 30 leaves some room. If you raise max_sessions_per_user in ALPS, raise this too. See Sessions-and-Sign-in.
  • Folders: ALPS never creates special folders, and files sent copies and drafts into the existing Sent and Drafts. auto = subscribe creates all five at the first sign-in. Dovecot lists SPECIAL-USE, so ALPS asks for the attributes when it lists the folders: the page shows each folder in its role, and ALPS files sent copies and drafts, by its special_use attribute rather than by its name.
  • Sieve: ALPS edits the user's active script in place. When the account has none, as on a new account, ALPS saves the filters as alps-filters (stored as ~/sieve/alps-filters.sieve) and makes it active. Dovecot runs the active script when LMTP delivers a message.
  • Sockets: Postfix reaches Dovecot's LMTP and authentication through the two sockets in /var/spool/postfix/private.

Dovecot 2.3 (Debian 12, Ubuntu 24.04): /etc/dovecot/dovecot.conf

The same setup in 2.3 syntax. It replaces the packaged file in the same way.

# /etc/dovecot/dovecot.conf for Dovecot 2.3 (Debian 12, Ubuntu 24.04)
protocols = imap lmtp sieve

# TLS: the certificate for mail.example.com
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem

# Users: full addresses as logins, in a passwd-file
auth_mechanisms = plain login
passdb {
  driver = passwd-file
  args = /etc/dovecot/users
}
userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/vmail/%d/%n
}

# Mail storage
mail_location = maildir:~/Maildir

# Folders ALPS files into or offers, created for every account
namespace inbox {
  inbox = yes
  separator = /
  mailbox Drafts {
    special_use = \Drafts
    auto = subscribe
  }
  mailbox Sent {
    special_use = \Sent
    auto = subscribe
  }
  mailbox Trash {
    special_use = \Trash
    auto = subscribe
  }
  mailbox Junk {
    special_use = \Junk
    auto = subscribe
  }
  mailbox Archive {
    special_use = \Archive
    auto = subscribe
  }
}

# METADATA: where ALPS keeps settings, identities, security keys and the
# OpenPGP keyring. Both parts are needed.
mail_attribute_dict = file:%h/dovecot-attributes
protocol imap {
  imap_metadata = yes
  # Every ALPS session connects from this host's address.
  mail_max_userip_connections = 30
}

# Sieve: filters and auto-reply run when LMTP delivers
plugin {
  sieve = file:~/sieve;active=~/.dovecot.sieve
}
protocol lmtp {
  mail_plugins = $mail_plugins sieve
}

service managesieve-login {
  inet_listener sieve {
    port = 4190
  }
}

# Postfix: delivery over LMTP, and SASL for submission
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
}

If you are adapting an existing Dovecot configuration, these are the settings that differ between the two versions:

Purpose Dovecot 2.4 Dovecot 2.3
METADATA store mail_attribute { dict file { path = %{home}/dovecot-attributes } } mail_attribute_dict = file:%h/dovecot-attributes
METADATA command imap_metadata = yes in protocol imap the same
Certificate ssl_server_cert_file = /path, ssl_server_key_file = /path ssl_cert = </path, ssl_key = </path
Mail location mail_driver = maildir, mail_path = ~/Maildir mail_location = maildir:~/Maildir
Home in the static userdb %{user | domain}/%{user | username} %d/%n
Sieve script location sieve_script personal { ... } plugin { sieve = file:~/sieve;active=~/.dovecot.sieve }
Sieve at delivery protocol lmtp { mail_plugins { sieve = yes } } protocol lmtp { mail_plugins = $mail_plugins sieve }

Mail users

Create the system user that owns the mail, the mail root and the user file:

groupadd --system --gid 5000 vmail
useradd --system --uid 5000 --gid vmail --home-dir /var/vmail --shell /usr/sbin/nologin vmail
install -d -o vmail -g vmail -m 0750 /var/vmail
install -o root -g dovecot -m 0640 /dev/null /etc/dovecot/users

useradd warns that uid 5000 is above SYS_UID_MAX. The warning is harmless, and the user is created.

Add a line to /etc/dovecot/users for each account. doveadm pw reads the password twice and prints its hash:

printf '%s:%s\n' alice@example.com "$(doveadm pw -s SHA512-CRYPT)" >> /etc/dovecot/users
printf '%s:%s\n' bob@example.com "$(doveadm pw -s SHA512-CRYPT)" >> /etc/dovecot/users

Each line looks like alice@example.com:{SHA512-CRYPT}$6$.... The user's home is /var/vmail/example.com/alice, and Dovecot creates it, with the folders, at the first sign-in. A line added while Dovecot runs works at once, with no reload.

Postfix: /etc/postfix/main.cf

Keep the main.cf the Debian package wrote, and set these on top of it:

postconf -e \
  'myhostname = mail.example.com' \
  'smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem' \
  'smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem' \
  'smtpd_tls_security_level = may' \
  'virtual_mailbox_domains = example.com' \
  'virtual_mailbox_maps = texthash:/etc/postfix/vmailbox' \
  'virtual_transport = lmtp:unix:private/dovecot-lmtp' \
  'smtpd_sender_login_maps = texthash:/etc/postfix/sender_login' \
  'message_size_limit = 52428800'
  • virtual_mailbox_domains, virtual_mailbox_maps and virtual_transport deliver mail for the addresses in /etc/postfix/vmailbox to Dovecot's LMTP socket. Postfix refuses mail for other addresses at example.com with 550 5.1.1 ... User unknown in virtual mailbox table.
  • smtpd_sender_login_maps says which login may send from which address. The submission service below uses it.
  • message_size_limit is 52428800 bytes (50 MiB). Postfix advertises it as SIZE in its answer to EHLO, and ALPS lowers the attachment limit of each composer to what fits in a message of that size once encoded. With 50 MiB, the whole max_attachment_mib (32 MiB by default) fits. With Postfix's default of 10240000 bytes, users could attach only about 7 MiB.

Postfix: /etc/postfix/master.cf

Debian's master.cf has a commented-out submission entry. Replace that entry and its commented -o lines with:

submission inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_tls_auth_only=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_sender_restrictions=reject_sender_login_mismatch
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
  • Port 587 requires STARTTLS before AUTH. ALPS's smtp:// always upgrades with STARTTLS, so this matches.
  • smtpd_sasl_type=dovecot checks the password through Dovecot's auth socket. ALPS authenticates with AUTH PLAIN, using the address and password the user signed in with.
  • reject_sender_login_mismatch lets a login send only from the addresses sender_login lists for it. ALPS sends MAIL FROM with the address chosen in the composer's From field, so every sending address a user adds in ALPS must be listed for that user's login.
  • Postfix does not save a copy of the message. ALPS files the sent copy in Sent itself over IMAP, so do not add anything that also saves submitted mail into Sent, or each sent message appears there twice.

Postfix: /etc/postfix/vmailbox and /etc/postfix/sender_login

/etc/postfix/vmailbox lists the addresses that receive mail. The second column only has to be present:

alice@example.com   OK
bob@example.com     OK

/etc/postfix/sender_login lists each sending address and the logins that may use it. Here Alice may also send as sales@example.com:

alice@example.com   alice@example.com
sales@example.com   alice@example.com
bob@example.com     bob@example.com

Both are texthash tables, so postmap is not needed. Postfix reads them when it starts or reloads, so run postfix reload after editing either one.

ALPS: /etc/alps/config.toml

[server]
addr = "127.0.0.1:1323"
trusted_proxies = ["127.0.0.1/32", "::1/128"]
login_key = "<output of: openssl rand -base64 32>"

[webauthn]
rpid = "webmail.example.com"
origins = ["https://webmail.example.com"]

[provider]
type = "imap"

[provider.imap]
server = "imaps://mail.example.com:993"

[smtp]
server = "smtp://mail.example.com:587"

[plugin.base]
enabled = true

[plugin.managesieve]
enabled = true
server = "managesieve://mail.example.com:4190"

[plugin.gpg]
enabled = true

Make the file readable by ALPS only, since it holds login_key:

chown root:alps /etc/alps/config.toml
chmod 0640 /etc/alps/config.toml

Notes on this file:

  • imaps:// is implicit TLS on 993. smtp:// is STARTTLS on 587, and the send fails if the server does not offer it. managesieve:// connects in plain TCP and upgrades with STARTTLS before it signs in. It is not implicit TLS. All three check the certificate against the system roots.
  • [server] and [webauthn] are the reverse-proxy settings from Setup-Behind-a-Reverse-Proxy. List only your own proxies in trusted_proxies.
  • login_key keeps sign-ins across ALPS restarts and makes "Stay signed in after closing the browser" possible (see Sessions-and-Sign-in). Keep it secret. Changing it signs everyone out, and users have to link their other accounts again.
  • enabled = true in these sections turns on the enabled list of plugins: only managesieve, gpg and base, which always loads, are on. While the list is on, a section that leaves enabled out keeps its plugin out too, and ManageSieve also needs its server. Calendars, contacts and password changes stay off. See Config-Plugins, and Setup-Password-Change for password changes.
  • Dovecot lists IDLE, NOTIFY and CONDSTORE, which ALPS uses only when you turn on push_new_mail, push_subscribed_folders and condstore (all off by default; see Config-Server). With push_new_mail, every open mail page holds two IMAP connections, which mail_max_userip_connections = 30 allows for.

Start it

Start Postfix before Dovecot. Dovecot creates its two sockets in /var/spool/postfix/private, and that directory exists only once Postfix has started at least once (the Debian package starts it when it is installed).

systemctl restart postfix
doveconf -n > /dev/null && systemctl restart dovecot
systemctl restart alps
journalctl -u alps -n 20

doveconf -n prints nothing here when the file is valid, and the line with the error otherwise. If the journal shows only Started alps.service, run journalctl -u alps -n 20 again a second later. ALPS logs these messages among others, as JSON lines unless [logging] sets another format:

Configured SMTP server: smtp://mail.example.com:587
Loaded plugin "base"
Loaded plugin "gpg"
Configured ManageSieve server: managesieve://mail.example.com:4190
Loaded plugin "managesieve"
Starting server on 127.0.0.1:1323

A line such as Unknown configuration key: plugin.managesieve.sever (ignored) names a key ALPS does not know and has ignored: correct its spelling.

systemctl reload alps only reopens a log file that [logging] output names. This file names none, so ALPS logs SIGHUP: no log file to reopen. Reload does not read config.toml again, as the comment in dist/alps.service says. Restart ALPS after every change to config.toml.

Dovecot and Postfix read the certificate when they start and when they reload, so after certbot renews it, run:

systemctl reload dovecot postfix

Check it works

Step 1 shows the password you type on the screen, so use a test account.

  1. Dovecot lists METADATA after sign-in.

    openssl s_client -quiet -crlf -connect mail.example.com:993

    Each certificate in the chain must show verify return:1. Then type:

    a LOGIN alice@example.com password
    b CAPABILITY
    c LOGOUT
    

    The a OK [CAPABILITY ...] line and the * CAPABILITY line must include METADATA.

  2. ManageSieve answers over STARTTLS.

    openssl s_client -quiet -crlf -starttls sieve -connect mail.example.com:4190

    The "SIEVE" line lists the extensions, vacation among them. Type LOGOUT to end. Without vacation, the Auto-reply tab says that the mail server does not offer automatic replies.

  3. Submission offers AUTH after STARTTLS.

    openssl s_client -quiet -crlf -starttls smtp -connect mail.example.com:587

    Type EHLO localhost. The answer must include 250-AUTH PLAIN LOGIN. Type QUIT to end.

  4. ALPS keeps a setting. Sign in at https://webmail.example.com as Alice, change something under Settings (the signature, for example) and save. Sign out and sign in again: the change is still there. On the host:

    doveadm mailbox metadata list -u alice@example.com -s ""
    journalctl -u alps | grep 'transient store'

    The first command lists vendor/alps/base.settings. The second prints nothing.

  5. Filters run on delivery. As Alice, create a folder named Invoices (Create Folder in the folder list), because the rule offers only folders that already exist. Then add a rule under Settings > Filters: Subject contains invoice, Move to folder Invoices. Save it. /var/vmail/example.com/alice/sieve/alps-filters.sieve now exists. Sign in as Bob and send Alice a message with "invoice" in the subject. It arrives in Alice's Invoices folder, and Bob's copy is in his Sent.

  6. Sending goes through Postfix. Debian 12 and 13 write no /var/log/mail.log unless rsyslog is installed, so read Postfix's lines from the journal:

    journalctl -t postfix/submission/smtpd -t postfix/lmtp -n 20

    The message from step 5 shows sasl_method=PLAIN, sasl_username=bob@example.com on the postfix/submission/smtpd line and status=sent (250 2.0.0 <alice@example.com> ... Saved) on the postfix/lmtp line.

  7. Sending addresses follow sender_login. As Alice, add sales@example.com under Settings > Identity > Sending addresses and send a message from it: it goes out. An address that sender_login does not list for Alice is refused: ALPS answers the send with 403 sender_not_allowed, and the composer says "You cannot send from this address. Choose another From address."

Adding users and sending addresses

For a new account:

  1. Add its line to /etc/dovecot/users with doveadm pw (see Mail users).
  2. Add the address to /etc/postfix/vmailbox, and the address with its own login to /etc/postfix/sender_login.
  3. Run postfix reload.

For a new sending address, add it to /etc/postfix/sender_login with the login that may use it, run postfix reload, and have the user add it under Settings > Identity > Sending addresses.

Sending from an address does not make it receive mail. To deliver mail for sales@example.com to Alice, add an alias:

echo 'sales@example.com   alice@example.com' >> /etc/postfix/virtual
postconf -e 'virtual_alias_maps = texthash:/etc/postfix/virtual'
postfix reload

Do not add such an address to /etc/postfix/vmailbox: Dovecot has no account by that name to deliver to.

Variations

Loopback for IMAP and ManageSieve

ALPS can reach IMAP and ManageSieve over the loopback address instead of the certificate's name:

[provider.imap]
server = "imap+insecure://127.0.0.1:143"

[plugin.managesieve]
enabled = true
server = "managesieve+insecure://127.0.0.1:4190"

The IMAP connection is then plaintext, and the ManageSieve connection uses STARTTLS without checking the certificate. Dovecot accepts the password on these connections even with ssl = required, because they come from the host itself. Keep smtp://mail.example.com:587 for sending: the submission service above requires TLS. Use these values only when ALPS and Dovecot run on the same host.

When mail.example.com does not lead back to this host

Some hosts cannot reach their own public address, for example behind NAT. Then add a line to /etc/hosts on the host:

127.0.0.1   mail.example.com

ALPS keeps using the name, so the certificate is still checked, and Dovecot and Postfix see the connections coming from 127.0.0.1.

Troubleshooting

Settings are gone at the next sign-in

Dovecot does not list METADATA. ALPS logs alps/provider: IMAP server doesn't support the METADATA extension, using transient store instead. Check that both parts are set:

doveconf -n | grep -A3 -E 'imap_metadata|mail_attribute'

The output must show imap_metadata = yes and the dictionary: a mail_attribute { dict file { ... } } block on 2.4, or mail_attribute_dict = file:%h/dovecot-attributes on 2.3. With only one of them set, Dovecot 2.4 and 2.3 both leave METADATA out of the capabilities. Fix the file, restart Dovecot, and check the capabilities as in step 1 of Check it works. Settings saved while METADATA was missing were never stored, so users must save them again.

Dovecot does not start: bind(/var/spool/postfix/private/...) failed

Error: bind(/var/spool/postfix/private/dovecot-lmtp) failed: No such file or directory
Error: bind(/var/spool/postfix/private/auth) failed: No such file or directory
Fatal: Failed to start listeners

/var/spool/postfix/private does not exist, because Postfix has never started on this host. The Debian package starts Postfix when it is installed, so this happens mostly where that did not run. Start Postfix, then Dovecot.

Dovecot 2.4 refuses the file

  • The first setting must be dovecot_config_version: something comes before dovecot_config_version, such as an !include line. Move dovecot_config_version to the top.
  • mail_attribute_dict: Unknown setting: mail_attribute_dict: a 2.3 setting in a 2.4 file. Use the 2.4 form from the table.

Sign-in says "Too many connections are open to this account"

Dovecot refused another connection for the user. Its log shows:

Maximum number of connections from user+IP exceeded (mail_max_userip_connections=10)

Every ALPS connection comes from this host's address, so they all count against one user-and-address limit. Raise mail_max_userip_connections in protocol imap as in the files above, and restart Dovecot.

Sending from an added address fails

The composer reports that the server refused the sender, and Postfix logs:

553 5.7.1 <ceo@example.com>: Sender address rejected: not owned by user alice@example.com

Add the address with the user's login to /etc/postfix/sender_login and run postfix reload. ALPS does not decide which addresses a login may use; Postfix does.

Sending a large message fails

The composer says "This message exceeds the mail server's size limit. Remove attachments or shorten the message and try again." and keeps the message. ALPS answered the send with 413 message_too_large and logged message size refused: .... A file larger than the attachment limit is refused as it is attached, with "Attachments exceed the maximum allowed size."

ALPS checks a message against the SIZE that Postfix advertises before it submits it, so a message too large for message_size_limit is refused before Postfix sees it. When that check could not be made, Postfix refuses the message with 552 and logs warning: ... queue file size limit exceeded, and ALPS gives the same answer. To allow larger messages, raise message_size_limit as in main.cf and run postfix reload.

Filters or the auto-reply do not load

The tabs show Could not load the filters. or Could not load the auto-reply., and ALPS logs the reason. When nothing listens on the ManageSieve port, the line reads:

managesieve: failed to connect to the sieve server: failed to connect to ManageSieve server: dial tcp 192.0.2.10:4190: connect: connection refused

Check that [plugin.managesieve] server is managesieve://mail.example.com:4190, that protocols in dovecot.conf includes sieve, and that step 2 of Check it works passes from the ALPS host. See docs/FILTERS.md.

Related pages

Tested with

ALPS main a5443047 (linux/arm64), tested on 2026-11-12. The Debian hosts were the Debian cloud images, run as virtual machines with systemd, and the page was followed from the package install to the last check:

  • Debian 13.7: dovecot 1:2.4.1+dfsg1-6+deb13u7 (Dovecot 2.4.1), Postfix 3.10.13, OpenSSL 3.5.7. Every step of Check it works (through ALPS's API rather than a browser), doveadm pw on a terminal, the start commands and systemctl reload alps under the shipped unit, the troubleshooting cases, both variations, a new account, the alias, a 30 MB attachment, and a certificate replaced and picked up by systemctl reload dovecot postfix.
  • Debian 12.15: dovecot 1:2.3.19.1+dfsg1-2.1+deb12u7 (Dovecot 2.3.19.1), Postfix 3.7.11, OpenSSL 3.0.22, with the 2.3 file. Every step of Check it works, the METADATA troubleshooting case, and the loopback variation.
  • Ubuntu 24.04.5 (in a container): dovecot 1:2.3.21+dfsg1-2ubuntu6.5 (Dovecot 2.3.21), Postfix 3.8.6, with the 2.3 file. Every step of Check it works, before message_size_limit was added.
  • The dovecot/dovecot:latest image (Dovecot 2.4.5): the 2.4 file without the Postfix sockets. METADATA, sign-in, settings kept across a new sign-in and an ALPS restart, and ManageSieve.
  • Not run: the dovecot/dovecot:2.3-latest image, a browser, and certbot itself.
  • Lab differences: a private CA in the system trust store stood in for Let's Encrypt, with the certificate at the same paths, and an /etc/hosts line pointed mail.example.com at the host's own address in place of DNS. The Postfix installer's questions were answered in advance with the values above. The checks were made against ALPS's API with the headers a reverse proxy on 127.0.0.1 sends.

Updated from the code at main 92ec0e11 without a rerun: special folders, which ALPS now finds by Dovecot's special-use attributes on the page too; the attachment limit that follows Postfix's advertised SIZE, and the answer to a message that is too large, which replaces the troubleshooting case of a general send failure; the plugin rules; the startup warning for unknown keys; and the order of the startup lines. The ALPS file above, alone and with the loopback variation, was started once with a 92ec0e11 build on macOS, to check that ALPS knows every key and to read the startup lines shown.

Clone this wiki locally