Postfix delivers messages locally instead of using an external agent when the recipient domain is listed in the local transport or virtual mailbox maps. This behavior overrides external SMTP relay settings, causing mail to be stored on the server rather than forwarded to a third-party provider like Gmail or AWS SES. Resolving this requires verifying main.cf parameters and checking alias databases to ensure no local delivery rules are inadvertently catching external addresses.
Understanding Local Delivery Mechanisms
Postfix determines how to handle incoming mail based on a series of configuration parameters defined in
/etc/postfix/main.cf. The most critical setting for this issue is
mydestination. This parameter lists the domains that the machine considers itself to be the final destination for. If an email address's domain matches any entry in
mydestination, Postfix assumes it should deliver the message to a local user mailbox, typically via Dovecot or a local MDA, bypassing any external relay configuration.
Another common culprit is the
virtual_mailbox_domains parameter. This is often used in multi-tenant setups where specific domains are hosted virtually on the server. If your external provider’s domain is accidentally added here, Postfix will attempt local delivery for all users within that domain. Additionally, the
relayhost setting defines the external server to which mail should be sent. However, if local delivery rules take precedence due to domain matching, the
relayhost will be ignored for those specific messages.
Checking Main Configuration Files
To diagnose the problem, you must inspect the primary configuration file. Open
/etc/postfix/main.cf with a text editor such as
nano or
vim. Look for the line starting with
mydestination. It might look something like this:
mydestination = $myhostname, localhost.$mydomain, localhost, example.com
If
example.com (your external provider's domain) appears in this list, remove it. Ensure that only the server’s hostname and localhost entries remain. Similarly, check for
virtual_mailbox_domains. If it contains your external domain, remove it from the list unless you intend to host that domain locally. After making changes, you must reload the Postfix service for the new configuration to take effect. Use the command
systemctl reload postfix or
postfix reload.
Verifying Alias and Virtual Maps
Beyond the main configuration, Postfix uses lookup tables to resolve recipients. These are defined by parameters like
alias_maps,
virtual_alias_maps, and
virtual_mailbox_maps. These maps point to files or database sources that map email addresses to other destinations. If an external domain is mapped to a local user in these tables, Postfix will deliver the mail locally.
Check the
aliases file, typically located at
/etc/aliases. This file handles basic system aliases. While less likely to cause widespread issues for entire domains, ensure no wildcard aliases are capturing external mail. For virtual domains, check the file specified in
virtual_alias_maps. This could be a flat file or a database query. If you are using a database, query it directly to see if any records match your external domain.
For example, if
virtual_alias_maps points to
hash:/etc/postfix/virtual, open that file and search for your external domain. Remove any entries that redirect external mail to local accounts. After editing these map files, you must regenerate the hash database. Run
postmap /etc/postfix/virtual if applicable, and then reload Postfix. Failure to run
postmap after modifying hash-based maps is a common source of persistent configuration errors.
DNS and MX Record Considerations
While DNS does not directly control Postfix’s internal decision-making for *incoming* mail delivery logic, it influences how other servers route mail to you. However, for outgoing mail, DNS plays a role in determining where to send messages if no explicit relay is configured. If you are experiencing issues with outgoing mail being treated as local, ensure that your
myorigin parameter is set correctly. This parameter defines the domain name that appears in emails sent from the server.
If
myorigin is set to a domain that is also in
mydestination, Postfix might get confused during local processing loops. Typically,
myorigin should be set to your primary domain, while
mydestination should include that domain and localhost. Ensure there is no circular reference that causes Postfix to think it is delivering mail to itself when it should be relaying.
Additionally, verify that your server’s reverse DNS (PTR record) matches your forward DNS (A record). While this primarily affects spam filtering by receiving servers, misconfigurations can sometimes lead to unexpected routing behaviors in complex network setups. If you are using a smart host for outgoing mail, ensure that the
relayhost is correctly formatted and that authentication credentials are valid. Invalid authentication can cause Postfix to fall back to local delivery or reject the mail entirely, depending on the
smtp_sasl_auth_enable settings.
Testing and Validation
After adjusting configurations, test the delivery mechanism thoroughly. Use the
sendmail command or a tool like
swaks to simulate sending an email to an external address. Monitor the mail log at
/var/log/mail.log or
/var/log/syslog for detailed transaction records. Look for lines indicating the transport method. You should see references to the external relay or the smart host, not
local or
dovecot.
If the issue persists, enable verbose logging temporarily by setting
debug_peer_list in
main.cf for the problematic domain. This provides extensive detail about how Postfix resolves the recipient and chooses the transport. Once debugging is complete, remove this setting to avoid performance impacts. Regularly review your configuration against best practices to prevent recurrence.
Fixing Debian Postfix, Dovecot, and SpamAssassin: External Emails Not Accepted, Outside Addresses Not Sent provides additional context on integrating local delivery agents with external security filters.
Frequently Asked Questions
How do I check if my domain is in mydestination?
Open
/etc/postfix/main.cf and search for the
mydestination line. Any domain listed there will be delivered locally. Remove your external provider’s domain from this list to force external delivery.
What happens if I forget to run postmap?
If you modify a hash-based map file like
/etc/postfix/virtual without running
postmap, Postfix will continue to use the old cached version. Your changes will have no effect until the database is regenerated and the service is reloaded.
Can virtual_alias_maps override mydestination?
Yes,
virtual_alias_maps are processed before local delivery decisions. If an address is mapped to an external address in this table, it will be relayed even if the domain is in
mydestination. However, relying on this for entire domains is inefficient; it is better to remove the domain from
mydestination.
Why is my mail still going local after changing main.cf?
Postfix caches certain configurations. Always run
postfix reload or
systemctl reload postfix after editing
main.cf. Additionally, check if another configuration file included via
include directives is overriding your settings.
How do I verify the current transport for a domain?
Use the command
postconf -m to see available lookup types and
postconf mydestination to view the current list. For real-time testing, send a test email and check the logs for the transport label associated with the delivery action.