How to Fix Postfix “Recipient address rejected: Access denied” Error in PHP/Zend Mail Applications


2 views

The "554 5.7.1 Recipient address rejected: Access denied" error typically occurs when Postfix's recipient restrictions block your outgoing mail. From your configuration, this is happening because:

smtpd_recipient_restrictions = permit_sasl_authenticated permit_mynetworks permit_tls_clientcerts reject_unauth_pipelining reject_non_fqdn_hostname reject_non_fqdn_sender reject_non_fqdn_recipient reject_unknown_recipient_domain reject_unauth_destination reject_invalid_hostname reject_rbl_client bl.spamcop.net reject_rbl_client b.barracudacentral.org reject_rbl_client sbl-xbl.spamhaus.org reject_rbl_client pbl.spamhaus.org reject_rbl_client zen.spamhaus.org reject_rhsbl_helo dbl.spamhaus.org reject_rhsbl_sender dbl.spamhaus.org permit

First, verify your SASL authentication is working properly. Create a test PHP script:

<?php
require_once 'Zend/Mail.php';
$mail = new Zend_Mail();
$mail->setBodyText('Test message');
$mail->setFrom('no-reply@mydomain.com', 'Test');
$mail->addTo('recipient@example.com', 'Recipient');
$mail->setSubject('Test Subject');

$config = array(
    'auth' => 'login',
    'username' => 'your_smtp_user',
    'password' => 'your_password',
    'ssl' => 'tls',
    'port' => 587
);

$transport = new Zend_Mail_Transport_Smtp('mail.mydomain.com', $config);
$mail->send($transport);
?>

Modify your main.cf to include these crucial settings:

# Relax recipient restrictions for authenticated users
smtpd_recipient_restrictions = 
    permit_sasl_authenticated,
    permit_mynetworks,
    reject_unauth_destination,
    reject_rbl_client zen.spamhaus.org,
    reject_rhsbl_sender dbl.spamhaus.org,
    permit

# Ensure proper SASL authentication
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous

Verify your Dovecot SASL configuration in /etc/dovecot/conf.d/10-master.conf:

service auth {
    unix_listener /var/spool/postfix/private/auth {
        mode = 0660
        user = postfix
        group = postfix
    }
}

Use these commands to diagnose the issue:

# Check if SASL is working
telnet localhost 25
ehlo localhost
# Should show AUTH PLAIN LOGIN

# Verify mail queue
postqueue -p

# Check mail logs in real-time
tail -f /var/log/maillog

For production environments, implement proper error handling:

try {
    $mail->send($transport);
} catch (Zend_Mail_Transport_Exception $e) {
    error_log("SMTP Error: " . $e->getMessage());
    // Implement retry logic or fallback
}

The "Recipient address rejected: Access denied" error in Postfix typically occurs when your mail server's security policies prevent email delivery to certain addresses. In this case, we're dealing with a PHP application using Zend Mail SMTP authentication that's hitting this restriction.

# Relevant postconf -n output highlights:
smtpd_recipient_restrictions = permit_sasl_authenticated permit_mynetworks [...] reject_unauth_destination
smtpd_client_restrictions = sleep 1,reject_unauth_pipelining,permit_sasl_authenticated

The error occurs specifically when trying to send to external domains (like hotmail.com) while authenticated users can send internally via telnet.

First, verify your Dovecot SASL authentication is working properly:

telnet localhost 143
a LOGIN username password
a LIST "" "*"
a LOGOUT

Then check Postfix's SASL debug logs:

# Add to main.cf
debug_peer_level = 2
debug_peer_list = 127.0.0.1

Here's a proper Zend Mail SMTP configuration that should work with your setup:

$options = [
    'name' => 'mail.mydomain.com',
    'host' => 'mail.mydomain.com',
    'port' => 587,
    'connection_class' => 'login',
    'connection_config' => [
        'username' => 'no-replay@mydomain.com',
        'password' => 'yourpassword',
        'ssl' => 'tls',
    ],
];
$transport = new Zend\Mail\Transport\Smtp($options);

Modify your smtpd_recipient_restrictions to properly handle authenticated users:

smtpd_recipient_restrictions = 
    permit_sasl_authenticated,
    permit_mynetworks,
    reject_unauth_destination,
    reject_non_fqdn_hostname,
    reject_non_fqdn_sender,
    reject_non_fqdn_recipient,
    reject_unknown_recipient_domain,
    reject_invalid_hostname,
    permit

Ensure your mynetworks includes all necessary IP ranges:

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 xx:xx:xx:xx/32

For sending to external domains like hotmail.com, you need either:

  • Proper relayhost configuration
  • Or authenticated SMTP with recipient verification disabled for authenticated users

Test with this telnet sequence:

telnet mail.mydomain.com 587
EHLO client.example.com
AUTH LOGIN
[base64-encoded-username]
[base64-encoded-password]
MAIL FROM: <no-replay@mydomain.com>
RCPT TO: <test@external.com>
DATA
Subject: Test
Test message
.
QUIT

Verify these critical parameters:

postconf -d | grep -E 'relay|smtpd_recipient|smtpd_client|mynetworks'
postconf -n | grep -E 'sasl|tls|mynetworks'

Check your mail logs in real-time during sending attempts:

tail -f /var/log/maillog | grep -i 'sasl\|auth\|reject'