Fixing Postfix-Dovecot LMTP “User doesn’t exist” Error When Using Full Email Address as Username


3 views

When integrating Postfix with Dovecot's LMTP service, a common issue arises where LMTP attempts to authenticate users using the complete email address (e.g., user@domain.com) rather than just the username portion. This occurs because Postfix by default passes the full recipient address to the LMTP service.

Jan 11 08:22:17 s18015955 postfix/lmtp[7374]: 3D84E19B0290E: to=, 
orig_to=, relay=iota.mydomain.eu[private/dovecot-lmtp], 
status=bounced (host iota.mydomain.eu[private/dovecot-lmtp] said: 
550 5.1.1  User doesn't exist: eudoxos@mydomain.eu)

The current setup typically involves these configurations:

# /etc/dovecot/conf.d/10-master.conf
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    group = postfix
    user = postfix
    mode = 0600
  }
}

# /etc/postfix/main.cf
mailbox_transport = lmtp:unix:private/dovecot-lmtp

We need to configure Dovecot to properly parse the username from full email addresses. This requires modifications in both Postfix and Dovecot configurations.

Option 1: Using Postfix recipient_delimiter

# /etc/postfix/main.cf
recipient_delimiter = +
mailbox_transport = lmtp:unix:private/dovecot-lmtp

Option 2: Dovecot auth_username_format

# /etc/dovecot/conf.d/10-auth.conf
auth_username_format = %n

Option 3: Combined LDAP Configuration

For systems using LDAP authentication:

# /etc/dovecot/conf.d/auth-ldap.conf.ext
user_attrs = uid=user

Here's a verified configuration that solves the issue:

# /etc/postfix/main.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
local_recipient_maps = $virtual_mailbox_maps

# /etc/dovecot/conf.d/10-auth.conf
auth_username_format = %n

# /etc/dovecot/conf.d/10-master.conf
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}
  • Verify Dovecot is actually using the modified configuration with dovecot -n
  • Check mail logs in real-time with tail -f /var/log/mail.log
  • Test LMTP delivery manually using telnet to the socket

When integrating Postfix with Dovecot's LMTP service, a common stumbling block occurs when the recipient address includes the domain portion (user@domain) in the username lookup. The system expects just the local part (user) for authentication, leading to the error:

550 5.1.1 <eudoxos@mydomain.eu> User doesn't exist: eudoxos@mydomain.eu

The current setup shows proper LMTP socket configuration in /etc/dovecot/conf.d/10-master.conf:

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

And the Postfix main.cf contains:

mailbox_transport = lmtp:unix:private/dovecot-lmtp

We need to modify Dovecot's configuration to handle domain-based addresses correctly. Add these settings to your Dovecot configuration (typically in /etc/dovecot/conf.d/10-auth.conf):

auth_username_format = %n
auth_default_realm = mydomain.eu

The %n format specifier extracts just the local part from user@domain addresses. For LDAP-specific configuration:

user_attrs = \
  =uid=%{ldap:uid}, \
  =home=/var/mail/%d/%n

user_filter = (&(objectClass=posixAccount)(uid=%n))

For more complex setups, consider Postfix's recipient_delimiter:

recipient_delimiter = +
local_recipient_maps = $virtual_mailbox_maps

Combine this with Dovecot's auth_username_chars setting:

auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@

After making these changes, test your configuration:

telnet localhost 25
EHLO localhost
MAIL FROM:<test@example.com>
RCPT TO:<eudoxos@mydomain.eu>

Check Dovecot logs for successful delivery:

tail -f /var/log/dovecot.log

For debugging, increase log level temporarily:

mail_debug = yes
auth_verbose = yes
auth_debug = yes