So far this problem seems to be reported only once here, where the cause was identified in the Dovecot quota check.
In this case it's the last of the smtpd_recipient_restrictions :
check_policy_service inet:localhost:12345
Actually, the problem disappears after removing it.
When the quota check is in place, the log reveals the following:
dovecot: quota-status(alias@example.com): auth-master: userdb lookup(alias@example.com): Started userdb lookup
dovecot: auth: master in: USER#0111#011alias@example.com#011service=quota-status
dovecot: auth: static(alias@example.com): Performing userdb lookup
dovecot: auth: sql(alias@example.com): Performing passdb lookup
dovecot: auth-worker: conn unix:auth-worker: Handling PASSL request
dovecot: auth-worker: sql(alias@example.com): Performing passdb lookup
dovecot: auth-worker: sql(alias@example.com): query: SELECT email as user, password FROM virtual_users WHERE email='alias@example.com';
dovecot: auth-worker: sql(alias@example.com): unknown user
dovecot: auth-worker: sql(alias@example.com): Finished passdb lookup
dovecot: auth-worker: conn unix:auth-worker: Finished
dovecot: auth: sql(alias@example.com): Finished passdb lookup
dovecot: auth: static(alias@example.com): Finished userdb lookup
dovecot: auth: userdb out: NOTFOUND#0111
dovecot: quota-status(alias@example.com): auth-master: userdb lookup(alias@example.com): auth USER input:
dovecot: quota-status(alias@example.com): auth-master: userdb lookup(alias@example.com): Userdb lookup failed
postfix/smtpd: NOQUEUE: reject: 554 5.7.1 <alias@example.com>: Recipient address rejected: Unknown user; from=<mymailgmail.com> to=<alias@example.com>
The problem is that query defined in etc/dovecot/dovecot-sql.conf.ext
searches the email only in the virtual_users
table:
query: SELECT email as user, password FROM virtual_users WHERE email='alias@example.com';
The Linode tutorial referenced above states at some point:
To use an alias as the username:
Add the alias as the source and destination email address to the virtual_aliases table.
Change the /etc/dovecot/dovecot-sql.conf.ext
file’s password_query value to:
password_query = SELECT email as user, password FROM virtual_users WHERE email=(SELECT destination FROM virtual_aliases WHERE source = '%u');
I opted for a slightly different solution, making an UNION of the two queries in order to search a virtual user first, then a virtual alias:
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u' \
UNION SELECT email as user, password FROM virtual_users WHERE email=(SELECT destination FROM virtual_aliases WHERE source = '%u');
This works just fine. Below is an excerpt of the log:
dovecot: quota-status(alias@example.com): auth-master: userdb lookup(alias@example.com): Started userdb lookup
dovecot: auth: master in: USER#0114#011alias@example.com#011service=quota-status
dovecot: auth: static(alias@example.com): Performing userdb lookup
dovecot: auth: sql(alias@example.com): Performing passdb lookup
dovecot: auth: sql(alias@example.com): username changed alias@example.com -> mail@example.com
dovecot: auth: sql(mail@example.com): Finished passdb lookup
dovecot: auth: static(mail@example.com): Finished userdb lookup
dovecot: auth: userdb out: USER#0114#011mail@example.com#011uid=5000#011gid=5000#011home=/var/mail/vhosts/example.com/mail
dovecot: auth-worker: conn unix:auth-worker: Handling PASSL request
dovecot: auth-worker: sql(alias@example.com): Performing passdb lookup
dovecot: auth-worker: sql(alias@example.com): query: SELECT email as user, password FROM virtual_users WHERE email='alias@example.com' UNION SELECT email as user, password FROM virtual_users WHERE email=(SELECT destination FROM virtual_aliases WHERE source='alias@example.com');
dovecot: auth-worker: sql(alias@example.com): username changed alias@example.com -> mail@example.com
dovecot: auth-worker: sql(mail@example.com): Finished passdb lookup
dovecot: auth-worker: conn unix:auth-worker: Finished
dovecot: quota-status(alias@example.com): auth-master: userdb lookup(alias@example.com): auth USER input: mail@example.com uid=5000 gid=5000 home=/var/mail/vhosts/example.com/mail
dovecot: quota-status(alias@example.com): auth-master: userdb lookup(alias@example.com): Finished userdb lookup
dovecot: quota-status(alias@example.com): changed username to mail@example.com
dovecot: quota-status(mail@example.com): Effective uid=5000, gid=5000, home=/var/mail/vhosts/example.com/mail
dovecot: lmtp(mail@example.com): auth-master: userdb lookup(mail@example.com): Started userdb lookup
dovecot: lmtp(mail@example.com): auth-master: userdb lookup(mail@example.com): auth USER input: mail@example.com uid=5000 gid=5000 home=/var/mail/vhosts/example.com/mail
dovecot: lmtp(mail@example.com): auth-master: userdb lookup(mail@example.com): Finished userdb lookup
dovecot: auth: master in: USER#0112#011mail@example.com#011service=lmtp
dovecot: auth: static(mail@example.com): Performing userdb lookup
dovecot: auth: sql(mail@example.com): Performing passdb lookup
dovecot: auth: sql(mail@example.com): Finished passdb lookup
dovecot: auth: static(mail@example.com): Finished userdb lookup
dovecot: auth: userdb out: USER#0112#011mail@example.com#011uid=5000#011gid=5000#011home=/var/mail/vhosts/example.com/mail
dovecot: auth-worker: conn unix:auth-worker: Handling PASSL request
dovecot: auth-worker: sql(mail@example.com): Performing passdb lookup
dovecot: auth-worker: sql(mail@example.com): query: SELECT email as user, password FROM virtual_users WHERE email='mail@example.com' UNION SELECT email as user, password FROM virtual_users WHERE email=(SELECT destination FROM virtual_aliases WHERE source='mail@example.com');
dovecot: auth-worker: sql(mail@example.com): Finished passdb lookup
dovecot: auth-worker: conn unix:auth-worker: Finished
dovecot: lmtp(mail@example.com): lmtp-server: conn unix: rcpt mail@example.com: Effective uid=5000, gid=5000, home=/var/mail/vhosts/example.com/mail
dovecot: lmtp(mail@example.com): lmtp-server: conn unix: rcpt mail@example.com: Mailbox INBOX: Mailbox opened because: lib-lda delivery
dovecot: lmtp(mail@example.com): saved mail to INBOX
postfix/lmtp: to=<mail@example.com>, orig_to=<alias@example.com>, relay=server.example.com[private/dovecot-lmtp], status=sent