What's Actually Happening

Your email system is failing to send or receive messages due to SMTP authentication failures or connection refused errors. Clients cannot authenticate with the mail server, outgoing emails fail with authentication errors, or connections to the SMTP server are rejected entirely. This affects application-generated emails, user notifications, transactional emails, and general email delivery.

The errors can originate from incorrect authentication credentials, misconfigured SMTP server settings, firewall or security group restrictions, SSL/TLS certificate issues, service not running, or incorrect port configurations. Email is critical for user communication, password resets, notifications, and business operations.

The Error You'll See

``` # Client-side errors SMTP Error: Could not authenticate Authentication failed - bad username or password 535 5.7.8 Username and Password not accepted 535 Incorrect authentication data 530 5.7.0 Must issue a STARTTLS command first 454 4.7.0 TLS not available due to local problem

# Connection refused errors Connection refused (111) Connection timed out (110) Network is unreachable (101) SMTP connect() failed SMTP server connection failed

# Server-side logs (Postfix) postfix/smtpd[12345]: warning: unknown[192.168.1.100]: SASL LOGIN authentication failed: authentication failure postfix/smtpd[12345]: NOQUEUE: reject: RCPT from unknown[192.168.1.100]: 554 5.7.1 <user@example.com>: Relay access denied postfix/smtpd[12345]: warning: SASL authentication failure: cannot connect to saslauthd server: No such file or directory

# Application errors Error: Email could not be sent. SMTP Error: Could not connect to SMTP host. PHPMailer: SMTP Error: Could not authenticate. Swift_TransportException: Connection could not be established with host smtp.example.com [Connection refused #111]

# Telnet test $ telnet smtp.example.com 587 Trying 203.0.113.50... telnet: connect to address 203.0.113.50: Connection refused telnet: Unable to connect to remote host

# OpenSSL test $ openssl s_client -connect smtp.example.com:465 -quiet 140123456789024:error:0200206F:system library:connect:Connection refused:../sysdeps/unix/sysv/linux/connect.c:111: ```

Why This Happens

  1. 1.SMTP service not running: Postfix, Sendmail, Exim, or other MTA service is stopped or crashed. Service needs to be restarted.
  2. 2.Wrong port configuration: SMTP uses different ports for different purposes (25, 465, 587, 2525). Client configured for wrong port.
  3. 3.Authentication not enabled: SMTP server doesn't have SASL authentication enabled, or authentication method doesn't match client.
  4. 4.Firewall blocking ports: iptables, ufw, firewalld, or cloud security groups blocking SMTP ports.
  5. 5.TLS/SSL issues: Certificate expired or invalid, wrong TLS mode (implicit vs explicit), or STARTTLS not configured.
  6. 6.Incorrect credentials: Wrong username/password, user doesn't exist, password expired, or app-specific password required.
  7. 7.Relay restrictions: Server configured to reject relay from client IP, or client not authenticated for relay.
  8. 8.DNS resolution issues: MX records incorrect, hostname doesn't resolve, or pointing to wrong server.
  9. 9.Resource limits: Max connections reached, rate limiting, or IP temporarily blocked.
  10. 10.Configuration errors: Main.cf (Postfix) or sendmail.cf has incorrect settings for authentication, network, or TLS.

Step 1: Verify SMTP Service Status

Check if mail server is running:

```bash # Check Postfix status systemctl status postfix service postfix status

# Check if Postfix is listening netstat -tlnp | grep :25 ss -tlnp | grep :25

# Check all SMTP ports netstat -tlnp | grep -E ':(25|465|587|2525)'

# Check Postfix processes ps aux | grep postfix

# Start Postfix if not running systemctl start postfix systemctl enable postfix

# Check for errors journalctl -u postfix -n 50

# Check mail log tail -f /var/log/mail.log tail -f /var/log/maillog # RHEL/CentOS

# Test local SMTP telnet localhost 25 # or nc -v localhost 25

# Expected response: # 220 mail.example.com ESMTP Postfix

# Test EHLO # In telnet session: # EHLO test.com # Should show capabilities including AUTH

# Quit # QUIT ```

For Sendmail:

```bash # Check Sendmail status systemctl status sendmail service sendmail status

# Check if running ps aux | grep sendmail

# Start Sendmail systemctl start sendmail systemctl enable sendmail

# Check configuration sendmail -bd -q30m

# Test echo "Subject: Test" | sendmail -v user@example.com ```

For Exim:

```bash # Check Exim status systemctl status exim4 systemctl status exim

# Check if running ps aux | grep exim

# Start Exim systemctl start exim4

# Test exim -bt user@example.com echo "Test" | mail -s "Test" user@example.com ```

Step 2: Configure SMTP Authentication

Enable and configure SASL authentication:

```bash # For Postfix, check if SASL is installed dpkg -l | grep sasl # Debian/Ubuntu rpm -qa | grep sasl # RHEL/CentOS

# Install if missing sudo apt-get install libsasl2-modules sasl2-bin sudo yum install cyrus-sasl cyrus-sasl-plain

# Check SASL service systemctl status saslauthd systemctl start saslauthd systemctl enable saslauthd ```

Configure Postfix for authentication:

bash
# Edit /etc/postfix/main.cf
sudo nano /etc/postfix/main.cf

```ini # /etc/postfix/main.cf

# Enable SMTP authentication smtpd_sasl_auth_enable = yes smtpd_sasl_type = cyrus smtpd_sasl_path = smtpd smtpd_sasl_local_domain = $myhostname smtpd_sasl_security_options = noanonymous, noplaintext smtpd_sasl_tls_security_options = noanonymous broken_sasl_auth_clients = yes

# TLS settings smtpd_tls_security_level = may smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt smtpd_tls_loglevel = 1 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# TLS for submission port smtpd_tls_security_level = encrypt # Force TLS on submission port smtpd_tls_auth_only = yes

# Allow authenticated users to relay smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination

# SMTP restrictions smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

# Network settings inet_interfaces = all inet_protocols = ipv4

# Relay relayhost = mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain mynetworks = 127.0.0.0/8 ```

Configure submission port (587) in master.cf:

bash
# Edit /etc/postfix/master.cf
sudo nano /etc/postfix/master.cf

```ini # /etc/postfix/master.cf

# SMTP on port 25 smtp inet n - y - - smtpd

# Submission on port 587 with TLS submission inet n - y - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_tls_auth_only=yes -o smtpd_reject_unlisted_recipient=no -o smtpd_client_restrictions=$mua_client_restrictions -o smtpd_helo_restrictions=$mua_helo_restrictions -o smtpd_sender_restrictions=$mua_sender_restrictions -o smtpd_recipient_restrictions= -o smtpd_relay_restrictions=permit_sasl_authenticated,reject -o milter_macro_daemon_name=ORIGINATING

# SMTPS on port 465 (implicit TLS) smtps inet n - y - - smtpd -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_reject_unlisted_recipient=no -o smtpd_client_restrictions=$mua_client_restrictions -o smtpd_helo_restrictions=$mua_helo_restrictions -o smtpd_sender_restrictions=$mua_sender_restrictions -o smtpd_recipient_restrictions= -o smtpd_relay_restrictions=permit_sasl_authenticated,reject -o milter_macro_daemon_name=ORIGINATING ```

Restart after changes:

```bash # Restart Postfix sudo systemctl restart postfix

# Test configuration sudo postfix check sudo postfix reload

# Verify settings postconf -n | grep sasl postconf -n | grep tls ```

Step 3: Create and Verify User Credentials

Set up authentication users:

```bash # Create system user sudo useradd -m -s /bin/bash mailuser sudo passwd mailuser

# Or use virtual users with SASL

# Create SASL password file sudo nano /etc/postfix/sasl_passwd ```

bash
# Format: [smtp.server]:port username:password
[smtp.gmail.com]:587 your-email@gmail.com:your-app-password
[smtp.sendgrid.net]:587 apikey:your-api-key

```bash # Create database sudo postmap /etc/postfix/sasl_passwd

# Set permissions sudo chown root:postfix /etc/postfix/sasl_passwd* sudo chmod 640 /etc/postfix/sasl_passwd*

# Add to main.cf for outbound relay sudo postconf -e 'smtp_sasl_auth_enable = yes' sudo postconf -e 'smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd' sudo postconf -e 'smtp_sasl_security_options = noanonymous' sudo postconf -e 'smtp_sasl_tls_security_options = noanonymous' sudo postconf -e 'smtp_use_tls = yes'

# Restart sudo systemctl restart postfix ```

Test authentication:

```bash # Test with telnet (port 25 or 587) telnet localhost 587

# In telnet session: # EHLO test.com # STARTTLS # (connection will switch to TLS, then) # EHLO test.com # AUTH LOGIN # (base64 encoded username, then password)

# Encode credentials echo -ne '\0user@example.com' | base64 echo -ne '\0password' | base64

# Or use openssl openssl s_client -connect localhost:587 -starttls smtp

# Use swaks for testing sudo apt-get install swaks swaks --to recipient@example.com --from sender@example.com \ --server localhost:587 --auth LOGIN --auth-user user@example.com \ --auth-password 'password' --tls

# Use sendemail sendemail -f sender@example.com -t recipient@example.com \ -s localhost:587 -xu user@example.com -xp password -o tls=yes ```

Step 4: Configure Firewall for SMTP Ports

Open required ports:

```bash # Check current firewall status sudo ufw status sudo iptables -L -n sudo firewall-cmd --list-all

# UFW (Ubuntu) sudo ufw allow 25/tcp # SMTP sudo ufw allow 587/tcp # Submission sudo ufw allow 465/tcp # SMTPS sudo ufw allow 110/tcp # POP3 (if needed) sudo ufw allow 995/tcp # POP3S (if needed) sudo ufw allow 143/tcp # IMAP (if needed) sudo ufw allow 993/tcp # IMAPS (if needed)

sudo ufw reload sudo ufw status

# iptables sudo iptables -A INPUT -p tcp --dport 25 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 587 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 465 -j ACCEPT

# Save iptables rules sudo iptables-save > /etc/iptables/rules.v4 # or sudo service iptables save

# firewalld (CentOS/RHEL) sudo firewall-cmd --permanent --add-service=smtp sudo firewall-cmd --permanent --add-port=587/tcp sudo firewall-cmd --permanent --add-port=465/tcp sudo firewall-cmd --reload

# Verify ports are open sudo nmap -sT -p 25,587,465 localhost ```

For cloud providers, check security groups:

```bash # AWS - check security group aws ec2 describe-security-groups --group-ids sg-xxx

# GCP - check firewall rules gcloud compute firewall-rules list

# Azure - check network security group az network nsg rule list --resource-group myRG --nsg-name myNSG

# Test from external # From another machine: telnet your-server.com 587 nc -zv your-server.com 587 ```

Step 5: Fix TLS/SSL Certificate Issues

Configure proper certificates:

```bash # Check current certificates openssl s_client -connect localhost:587 -starttls smtp 2>/dev/null | openssl x509 -noout -dates

# For Let's Encrypt certificates sudo apt-get install certbot

# Get certificate sudo certbot certonly --standalone -d mail.example.com

# Copy to Postfix sudo cp /etc/letsencrypt/live/mail.example.com/fullchain.pem /etc/postfix/cert.pem sudo cp /etc/letsencrypt/live/mail.example.com/privkey.pem /etc/postfix/key.pem sudo chown root:root /etc/postfix/*.pem sudo chmod 600 /etc/postfix/key.pem ```

Configure Postfix for Let's Encrypt:

```bash sudo postconf -e 'smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem' sudo postconf -e 'smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem' sudo postconf -e 'smtpd_tls_CAfile = /etc/letsencrypt/live/mail.example.com/chain.pem'

# For outbound TLS sudo postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt' sudo postconf -e 'smtp_tls_security_level = may'

sudo systemctl restart postfix ```

Test TLS configuration:

```bash # Test STARTTLS on port 587 openssl s_client -connect localhost:587 -starttls smtp

# Test SMTPS on port 465 openssl s_client -connect localhost:465

# Check certificate openssl s_client -connect localhost:587 -starttls smtp 2>/dev/null | openssl x509 -noout -text

# Test from remote openssl s_client -connect mail.example.com:587 -starttls smtp openssl s_client -connect mail.example.com:465

# Check certificate validity echo | openssl s_client -servername mail.example.com -connect mail.example.com:587 -starttls smtp 2>/dev/null | openssl x509 -noout -dates ```

Step 6: Fix Relay Access Denied Errors

Configure proper relay permissions:

```bash # Check current relay settings postconf | grep relay

# Allow authenticated users to relay sudo postconf -e 'smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination'

# Configure mynetworks carefully sudo postconf -e 'mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128'

# For specific IP ranges sudo postconf -e 'mynetworks = 127.0.0.0/8 192.168.1.0/24 10.0.0.0/8'

# Check mydestination sudo postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain'

# If using virtual domains sudo postconf -e 'virtual_mailbox_domains = example.com, other.com' sudo postconf -e 'virtual_mailbox_base = /var/mail/vhosts' sudo postconf -e 'virtual_mailbox_maps = hash:/etc/postfix/vmailbox' sudo postconf -e 'virtual_uid_maps = static:5000' sudo postconf -e 'virtual_gid_maps = static:5000'

# Create virtual mailbox map sudo nano /etc/postfix/vmailbox ```

bash
user@example.com    example.com/user/
info@example.com    example.com/info/
bash
sudo postmap /etc/postfix/vmailbox
sudo systemctl restart postfix

Step 7: Debug SMTP Connections

Comprehensive connection debugging:

bash
# Full SMTP transaction test
telnet mail.example.com 587

``` # In telnet session: EHLO test.com STARTTLS # (After TLS starts) EHLO test.com AUTH LOGIN # (Enter base64 username) # (Enter base64 password) MAIL FROM: sender@example.com RCPT TO: recipient@example.com DATA Subject: Test Message

This is a test message. . QUIT ```

```bash # Using swaks for detailed debugging swaks --to recipient@example.com \ --from sender@example.com \ --server mail.example.com:587 \ --auth LOGIN \ --auth-user user@example.com \ --auth-password 'password' \ --tls \ --header "Subject: Test" \ --body "Test message" \ --timeout 30 \ --copy-on-error /tmp/smtp-error.log

# Using curl curl --url 'smtp://mail.example.com:587' \ --mail-from 'sender@example.com' \ --mail-rcpt 'recipient@example.com' \ --user 'user@example.com:password' \ --upload-file email.txt \ --ssl-reqd \ -v

# Check logs during test sudo tail -f /var/log/mail.log ```

Step 8: Configure Application Email Settings

Set up applications to use SMTP correctly:

```php <?php // PHP with PHPMailer use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP;

$mail = new PHPMailer(true);

try { // Server settings $mail->SMTPDebug = SMTP::DEBUG_SERVER; // Enable debug output $mail->isSMTP(); $mail->Host = 'smtp.example.com'; $mail->SMTPAuth = true; $mail->Username = 'user@example.com'; $mail->Password = 'your-password'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // or ENCRYPTION_SMTPS $mail->Port = 587; // 465 for SMTPS

// Recipients $mail->setFrom('from@example.com', 'Sender Name'); $mail->addAddress('recipient@example.com', 'Recipient Name');

// Content $mail->isHTML(true); $mail->Subject = 'Test Email'; $mail->Body = 'This is a test email.';

$mail->send(); echo 'Message has been sent'; } catch (Exception $e) { echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}"; } ?> ```

```python # Python with smtplib import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart

def send_email(): smtp_server = "smtp.example.com" port = 587 sender_email = "user@example.com" password = "your-password"

message = MIMEMultipart("alternative") message["Subject"] = "Test Email" message["From"] = sender_email message["To"] = "recipient@example.com"

text = "This is a test email." part = MIMEText(text, "plain") message.attach(part)

try: server = smtplib.SMTP(smtp_server, port) server.starttls() # Secure the connection server.login(sender_email, password) server.sendmail(sender_email, "recipient@example.com", message.as_string()) print("Email sent successfully") except Exception as e: print(f"Error: {e}") finally: server.quit()

send_email() ```

```javascript // Node.js with nodemailer const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({ host: 'smtp.example.com', port: 587, secure: false, // true for 465, false for other ports auth: { user: 'user@example.com', pass: 'your-password' }, tls: { rejectUnauthorized: false // Only for testing } });

async function sendEmail() { try { const info = await transporter.sendMail({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Test Email', text: 'This is a test email.', html: '<p>This is a test email.</p>' }); console.log('Message sent: %s', info.messageId); } catch (error) { console.error('Error sending email:', error); } }

sendEmail(); ```

Step 9: Check DNS Configuration

Verify DNS records:

```bash # Check MX records dig MX example.com nslookup -type=MX example.com host -t MX example.com

# Check A record dig A mail.example.com nslookup mail.example.com

# Check PTR record (reverse DNS) dig -x 203.0.113.50 nslookup 203.0.113.50

# Check SPF record dig TXT example.com | grep spf nslookup -type=TXT example.com

# Check DKIM dig TXT default._domainkey.example.com

# Check DMARC dig TXT _dmarc.example.com

# All-in-one check dig +short MX example.com dig +short A mail.example.com

# Test from external # https://mxtoolbox.com/ # https://www.mail-tester.com/ ```

Set up proper DNS records:

```dns # A record for mail server mail.example.com. IN A 203.0.113.50

# MX record example.com. IN MX 10 mail.example.com.

# SPF record example.com. IN TXT "v=spf1 ip4:203.0.113.50 ~all"

# DKIM record (after generating key) default._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3..."

# DMARC record _dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com" ```

Step 10: Monitor and Maintain Email Service

Set up monitoring:

```bash #!/bin/bash # monitor_smtp.sh

SERVER="localhost" PORT=587 TIMEOUT=5

# Check SMTP port if ! nc -z -w $TIMEOUT $SERVER $PORT 2>/dev/null; then echo "CRITICAL: SMTP port $PORT is not responding" # Alert via other means exit 2 fi

# Check STARTTLS if ! echo "QUIT" | openssl s_client -connect $SERVER:$PORT -starttls smtp -quiet 2>/dev/null; then echo "WARNING: STARTTLS not working on port $PORT" exit 1 fi

# Check authentication # Requires swaks if command -v swaks &> /dev/null; then swaks --server $SERVER:$PORT --auth LOGIN --auth-user test@example.com \ --auth-password test --tls --quit-after AUTH 2>&1 | grep -q "Accepted" if [ $? -eq 0 ]; then echo "OK: SMTP authentication working" exit 0 else echo "WARNING: SMTP authentication may have issues" exit 1 fi fi

echo "OK: SMTP service is running" exit 0 ```

Set up log monitoring:

```bash # Watch for authentication failures tail -f /var/log/mail.log | grep --line-buffered "authentication failed"

# Monitor connections tail -f /var/log/mail.log | grep --line-buffered "connect from"

# Monitor TLS issues tail -f /var/log/mail.log | grep --line-buffered -i "tls|ssl"

# Create log monitoring cron cat <<EOF | sudo tee /etc/cron.d/monitor-smtp */5 * * * * root tail -100 /var/log/mail.log | grep -c "authentication failed" | awk '{if (\$1 > 10) system("echo Too many auth failures | mail -s SMTP Alert admin@example.com")}' EOF ```

Checklist

StepActionVerified
1Verified SMTP service status
2Configured SMTP authentication
3Created and verified user credentials
4Configured firewall for SMTP ports
5Fixed TLS/SSL certificate issues
6Fixed relay access denied errors
7Debugged SMTP connections
8Configured application email settings
9Checked DNS configuration
10Set up monitoring

Verify the Fix

  1. 1.Test SMTP connection:
  2. 2.```bash
  3. 3.telnet mail.example.com 587
  4. 4.`
  5. 5.Test authentication:
  6. 6.```bash
  7. 7.swaks --server mail.example.com:587 --auth LOGIN --auth-user user@example.com --auth-password password --tls
  8. 8.`
  9. 9.Test TLS:
  10. 10.```bash
  11. 11.openssl s_client -connect mail.example.com:587 -starttls smtp
  12. 12.`
  13. 13.Send test email:
  14. 14.```bash
  15. 15.echo "Test body" | mail -s "Test Subject" recipient@example.com
  16. 16.`
  • [Fix Postfix SMTP Server Not Sending Email](/articles/fix-postfix-smtp-server-not-sending-email)
  • [Fix Email Delivery Failure Bounce Back](/articles/fix-email-delivery-failure-bounce-back)
  • [Fix Email SPF DKIM DMARC Failures](/articles/fix-email-spf-dkim-dmarc-failures)
  • [Fix Gmail SMTP Authentication Error](/articles/fix-gmail-smtp-authentication-error)
  • [Fix Email Queued Not Sending](/articles/fix-email-queued-not-sending)