Virtual inbox in imap with dovecot 2.4
Hello,
I've recently upgraded to debian 13 (trixie), from debian 12 (bookworm). In bookworm I had the following setup working like perfection:
- All mail is sorted to some mailbox folder through sieve (either a "specialized" one, or a generic folder under the inbox name like year.month - 2025.08).
- No email whatsoever was ever reaching the inbox.
- Then I had a virtual inbox which would get me all the "unread" or "flagged" messages
This way I had all my email sorted out from the delivery and my inbox cleared itself once I had read an email.
For this I was using the stock debian dovecot packages, and now, after the upgrade to debian 13 I'm also using the stock debian packages.
However, this whole neat setup broke and I can't get it to work again. I've searched dovecot's manual, asked two different AIs, did a number of web searches and adapted the new configuration files to the new syntax but dovecot refuses to list the emails in my INBOX folder. I've spent already several hours around this, to no avail. Unfortunately I didn't keep a copy of the config files from debian 12 so now I can't really compare but I did manually change the dovecot config files after the upgrade so that what I had running in debian 12 should work as before (it was refusing to start after the upgrade).
Here is the output of dovecot -n
2.4.1-4 (7d8c0e5759): /etc/dovecot/dovecot.conf
Pigeonhole version 2.4.1-4 (0a86619f)
OS: Linux 6.12.41+deb13-amd64 x86_64 Debian 13.0
Hostname: myhost
4 default setting changes since version 2.4.0
dovecot_config_version = 2.4.0 auth_mechanisms = plain login dovecot_storage_version = 2.4.0 fts_autoindex = yes fts_autoindex_max_recent_msgs = 999 fts_search_add_missing = yes lda_mailbox_autocreate = yes lda_mailbox_autosubscribe = yes mail_driver = maildir mail_inbox_path = ~/Maildir mail_path = ~/Maildir mail_plugins { notify = yes mail_log = yes virtual = yes } mail_privileged_group = mail namespace_subscriptions = no protocols { imap = yes sieve = yes } passdb pam { } userdb passwd { } namespace inbox { inbox = yes prefix = separator = . subscriptions = yes mailbox Drafts { special_use = "\\Drafts" } mailbox Junk { special_use = "\\Junk" } mailbox Trash { special_use = "\\Trash" } mailbox Sent { special_use = "\\Sent" } mailbox "Sent Messages" { special_use = "\\Sent" } } service imap-login { inet_listener imap { } inet_listener imaps { } } service pop3-login { inet_listener pop3 { } inet_listener pop3s { } } service submission-login { inet_listener submission { port = 587 } inet_listener submissions { } } service lmtp { unix_listener lmtp { } } service imap { executable = imap imap-postlogin } service pop3 { } service submission { } service auth { unix_listener auth-userdb { } unix_listener /var/spool/postfix/private/auth { group = postfix mode = 0660 user = postfix } } service auth-worker { } service dict { unix_listener dict { } } ssl_server { cert_file = /etc/dovecot/private/dovecot.pem dh_file = /usr/share/dovecot/dh.pem key_file = /etc/dovecot/private/dovecot.key } protocol lda { mail_plugins { sieve = yes } } protocol imap { mail_max_userip_connections = 40 } service managesieve-login { inet_listener sieve { port = 4190 } } namespace 00-virtual { mail_driver = virtual mail_path = ~/Maildir/virtual hidden = no inbox = no list = yes prefix = 00-virtual. separator = . } namespace virtual { mail_driver = virtual mail_path = ~/Maildir/virtual hidden = no inbox = no list = yes prefix = virtual. separator = . } namespace real { hidden = yes inbox = no list = no prefix = real. separator = . subscriptions = no } service imap-postlogin { executable = script-login /usr/local/bin/dovecot-postlogin.sh unix_listener imap-postlogin { } } passdb deny { deny = yes driver = passwd-file passwd_file_path = /etc/dovecot/deny-users }
This is /usr/local/bin/dovecot-postlogin.sh #!/bin/sh VIRTUAL=$HOME/Maildir/virtual
AUTOMATICALLY VIRTUALIZE INBOX
If the user creates a virtual/INBOX/dovecot-virtual,
switch the inbox to the virtual namespace.
if [ -d "${VIRTUAL}/INBOX" ]; then export USERDB_KEYS="$USERDB_KEYS NAMESPACE/VIRTUAL/INBOX NAMESPACE/INBOX/INBOX" logger -p mail.debug "$USERDB_KEYS $VIRTUAL $@" /usr/bin/env USERDB_KEYS="$USERDB_KEYS" NAMESPACE/VIRTUAL/INBOX=yes NAMESPACE/INBOX/INBOX=no "$@" else exec "$@" fi
This is the content of $HOME/Maildir/virtual/INBOX/dovecot-virtual real.* OR UNSEEN FLAGGED
I'm also getting this message anytime that I login with a mail client: 2025-08-22T21:52:29.466584+01:00 ****** dovecot: imap(***)<316863><svBRYvo8+pXAqFoB>: Error: Mailbox INBOX: Failed to autocreate mailbox: Can't create virtual mailboxes
Note that the 00-virtual namespace was added just as a temporary check and I want to delete it once this is working again.
I have also a file under $HOME/Maildir/virtual/Flagged/dovecot-virtual with the exact same contents as the INBOX one above which get's me a virtual folder that works correctly (getting all my unread and flagged email in a single folder), so the filter works. Just changing the INBOX from the real to the virtual one fails and I can't understand what am I doing wrong or what am I missing.
Can someone please help me? I'm completely lost and frustrated on this.
Thank you very much.
Hello, Finally solved it. The namespace declarations must be like this: namespace inbox { prefix = separator = . list = yes inbox = yes }
namespace virtual { prefix = virtual. separator = . mail_driver = virtual mail_path = ~/Maildir/virtual mail_index_path = ~/Maildir/virtual/ mail_inbox_path = ~/Maildir/virtual/INBOX list = no hidden = yes inbox = no }
Then the dovecot-postlogin.sh script remains and changes the inbox between the two namespaces. The key point here I think are the two lines: mail_index_path = ~/Maildir/virtual/ mail_inbox_path = ~/Maildir/virtual/INBOX
With the above configuration and the rest of the config being equal everything now works again! I also had to delete the dovecot.index* on both ~/Maildir/virtual/ and ~/Maildir/virtual/INBOX Hope this helps somebody else.
Regards, Antonio
participants (1)
-
aholiveira@gmail.com