Troubleshooting Email
Troubleshooting email configuration in Password Pusher.
Email configuration in Password Pusher can be challenging due to the variety of SMTP servers, authentication methods, firewalls, and security policies. This guide helps you diagnose and resolve common email delivery issues.
Table of Contents
- Overview
- Quick Diagnosis
- Common Issues and Solutions
- Azure-Specific Issues
- Known Working Configurations
- Configuration Methods
- Example Success Output
- Troubleshooting Checklist
- Getting Additional Help
- See Also
Overview
Password Pusher uses SMTP (Simple Mail Transfer Protocol) to send emails for:
- User registration confirmations
- Password reset requests
- Account unlock notifications
- Administrative notifications
Prerequisites: Email functionality requires SMTP configuration. If you don’t need email features (e.g., logins disabled), SMTP configuration is optional.
Quick Diagnosis
Step 1: Enable Error Reporting
Enable raise_delivery_errors to see detailed error messages when emails fail:
Using Environment Variables:
PWP__MAIL__RAISE_DELIVERY_ERRORS=true
Using settings.yml:
mail:
raise_delivery_errors: true
Note: With raise_delivery_errors: false, email failures may be silently ignored, making troubleshooting difficult.
Step 2: Test Email Delivery
The quickest way to diagnose SMTP issues is to manually send a test email from the application console. This will display the exact error message if delivery fails.
Accessing the Application Console
Using Docker Compose:
docker compose exec pwpush bin/pwpush console
Using Docker Run:
docker exec -it <container_id> bin/pwpush console
For detailed instructions, see How to Access the Application Console.
Send a Test Email
Once in the console, run this command (replace with your email address):
TestMailer.send_test_email("your-email@example.com").deliver_now
Version Requirement: The TestMailer.send_test_email command is available since v1.39.8. Ensure you’re running that version or later.
Interpreting Results
On Success:
- You’ll see confirmation messages
- The email will arrive in your inbox
- No errors will be displayed
On Error:
- Detailed error messages will be displayed
- Common errors include authentication failures, connection timeouts, or server rejections
- Use these error messages to identify the specific issue
Step 3: View SMTP Configuration
To verify your SMTP settings are correctly loaded, check the configuration in the console:
Rails.application.config.action_mailer.smtp_settings
This will output all SMTP settings. Verify that:
- Server address is correct
- Port number matches your SMTP server
- Authentication credentials are present (if required)
- STARTTLS settings match your server requirements
Security Note: When sharing configuration output for troubleshooting, remove sensitive information (passwords, API keys) before posting.
Common Issues and Solutions
Authentication Errors
“Application-specific password required” (Gmail)
Error:
Net::SMTPAuthenticationError: 534-5.7.9 Application-specific password required.
Solution: Gmail requires an application-specific password, not your regular account password.
- Enable 2-Step Verification in your Google Account
- Generate an Application-Specific Password
- Use this password in your SMTP configuration
Gmail Configuration:
mail:
raise_delivery_errors: true
smtp_address: smtp.gmail.com
smtp_port: 587
smtp_authentication: plain
smtp_user_name: <your-gmail-email>
smtp_password: <application-specific-password>
smtp_enable_starttls_auto: true
smtp_open_timeout: 10
smtp_read_timeout: 10
“Authentication method not supported” (Microsoft 365)
Error:
Net::SMTPAuthenticationError: Authentication method "plain" isn't supported
Solution:
Microsoft 365/Exchange Online requires login authentication instead of plain.
Microsoft 365 Configuration:
mail:
raise_delivery_errors: true
smtp_address: 'smtp.office365.com'
smtp_user_name: 'your-email@domain.com'
smtp_password: 'your-password'
smtp_port: '587'
smtp_authentication: 'login' # Use 'login' not 'plain'
smtp_starttls: true
smtp_enable_starttls_auto: true
smtp_open_timeout: 10
smtp_read_timeout: 10
mailer_sender: '"Password Pusher" <your-email@domain.com>'
Connection Timeouts
“Connection timeout” or “Connection refused”
Symptoms:
- Emails fail to send
- Timeout errors in logs
- Connection refused errors
Solutions:
- Check SMTP server address:
# Test DNS resolution nslookup smtp.example.com # Test connectivity telnet smtp.example.com 587 - Verify port number:
- Port 587: STARTTLS (most common)
- Port 465: SSL/TLS (less common)
- Port 25: Unencrypted (often blocked)
- Check firewall rules:
- Ensure outbound connections to SMTP port are allowed
- Some networks block SMTP ports
- Increase timeout values:
mail: smtp_open_timeout: 30 # Increase from default 10 smtp_read_timeout: 30 # Increase from default 10
STARTTLS Issues
“STARTTLS not supported” or “SSL/TLS errors”
Symptoms:
- Connection fails after STARTTLS negotiation
- SSL certificate errors
Solutions:
- Try disabling STARTTLS:
mail: smtp_starttls: false smtp_enable_starttls_auto: false - Use SSL/TLS on port 465:
mail: smtp_address: smtp.example.com smtp_port: 465 smtp_starttls: false smtp_enable_starttls_auto: false - Verify server supports STARTTLS:
# Test STARTTLS support openssl s_client -connect smtp.example.com:587 -starttls smtp
Server Rejection
“Mail server rejected message”
Symptoms:
- Emails rejected by SMTP server
- “Relay access denied” errors
- “Sender address not allowed” errors
Solutions:
- Verify sender address:
- Ensure
mailer_sendermatches your SMTP account - Some servers require sender to match authenticated user
- Ensure
- Check relay restrictions:
- Some SMTP servers only allow sending from specific IPs
- Verify your server IP is whitelisted
- Review server logs:
- Check SMTP server logs for specific rejection reasons
- Common issues: SPF, DKIM, or DMARC failures
Configuration Not Loading
Settings not taking effect
Symptoms:
- Changes to SMTP settings don’t apply
- Old configuration still in use
Solutions:
- Restart the container:
docker compose restart pwpush # or docker restart <container_id> - Check configuration priority:
- Environment variables override
settings.yml - Verify you’re setting values in the correct place
- Environment variables override
- Verify environment variables:
docker compose exec pwpush env | grep PWP__MAIL
Azure-Specific Issues
Microsoft 365 Timeouts on Azure VMs
Symptoms:
Net::ReadTimeouterrors when sending email via Microsoft 365 (smtp.office365.com)- TCP connection succeeds but hangs during STARTTLS negotiation
- OpenSSL tests work, but Ruby/Rails
Net::SMTPfails - Same credentials work from other locations (workstation, different cloud provider)
Example Error:
Net::ReadTimeout with #<TCPSocket: closed>
Root Causes:
- Microsoft 365 Conditional Access Policies (Most Common)
- Your Azure VM’s public IP may be blocked by Conditional Access policies
- The connection opens but authentication is silently rejected, causing timeouts
- Azure Outbound SMTP Restrictions
- Some Azure subscription types (Pay-As-You-Go, trials, MSDN) restrict outbound SMTP
- Can affect port 587 with STARTTLS
- Docker MTU Mismatch
- Azure VNets may have effective MTU < 1500 due to encapsulation
- Docker default MTU is 1500, causing large TLS handshake packets to be dropped
Diagnostic Tools
Use these tools from inside the container to diagnose Azure-specific issues:
1. OpenSSL Test (Basic Connectivity)
# Test STARTTLS support
openssl s_client -connect smtp.office365.com:587 -starttls smtp
Success: Shows TLS 1.3 handshake completion Failure: Indicates network-level blocking or MTU issues
2. swaks (SMTP Swiss Army Knife)
Install and run swaks from the container:
# Install swaks
apt-get update && apt-get install -y swaks
# Test SMTP with verbose output
swaks --to test@example.com \
--from your-email@domain.com \
--server smtp.office365.com:587 \
--auth LOGIN \
--auth-user your-email@domain.com \
--auth-password 'your-password' \
--tls \
--verbose
Success: Reaches authentication stage (may fail with 535 for wrong password) Timeout: Indicates Conditional Access blocking or network issues
3. Ruby Diagnostic Script
From the application console, test SMTP step-by-step:
# Access console
docker compose exec pwpush bin/pwpush console
# Test basic SMTP connection
require 'net/smtp'
begin
smtp = Net::SMTP.start('smtp.office365.com', 587, 'localhost')
puts "Connected: #{smtp.started?}"
smtp.finish
rescue => e
puts "Error: #{e.class} - #{e.message}"
end
# Test with STARTTLS
begin
smtp = Net::SMTP.new('smtp.office365.com', 587)
smtp.enable_starttls
smtp.start('localhost', 'your-email@domain.com', 'your-password', :login) do |
puts "STARTTLS + Auth succeeded!"
end
rescue => e
puts "Error: #{e.class} - #{e.message}"
end
4. Check Docker MTU
# Inside container - check interface MTU
ip link show eth0 | grep mtu
# On host - check Docker network MTU
docker network inspect bridge -f '{{.Options}}'
# Check Azure VM effective MTU
ping -M do -s 1472 smtp.office365.com
# If "Frag needed" appears, MTU issues exist
Solutions
Fix 1: Whitelist Azure VM IP in Conditional Access
- In Microsoft 365 Admin Center, go to Security & Privacy → Conditional Access
- Check for policies blocking “Legacy authentication” or “Client apps”
- Add your Azure VM’s public IP to Named Locations or create an exclusion
- Or disable the blocking policy temporarily for testing
Fix 2: Reduce Docker MTU
Add MTU configuration to docker-compose.yml:
services:
pwpush:
# ... other config
networks:
- pwpush-network
networks:
pwpush-network:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: 1400
Restart containers:
docker compose down
docker compose up -d
Fix 3: Request Azure SMTP Exemption
If you have a restricted Azure subscription:
- Go to Azure Support
- Create a new support request
- Issue type: Technical → Networking → Virtual Network → Connectivity
- Request removal of outbound SMTP restriction for port 587
Fix 4: Alternative SMTP Configuration
Consider these workarounds:
- Use a different SMTP provider (SendGrid, Amazon SES) not subject to M365 policies
- Enable SMTP AUTH for specific mailbox in Exchange Admin Center
- Use a dedicated relay server outside Azure
Verification Checklist
After applying fixes, verify with:
openssl s_client -starttls smtpsucceeds from containerswaksreaches authentication stage (even if auth fails)- Ruby
Net::SMTPwith STARTTLS completes handshake TestMailer.send_test_emailsends successfully
Known Working Configurations
Gmail
Gmail requires an application-specific password (not your regular password).
mail:
raise_delivery_errors: true
smtp_address: smtp.gmail.com
smtp_port: 587
smtp_authentication: plain
smtp_user_name: <your-gmail-email>
smtp_password: <application-specific-password>
smtp_enable_starttls_auto: true
smtp_open_timeout: 10
smtp_read_timeout: 10
Environment Variables:
PWP__MAIL__RAISE_DELIVERY_ERRORS=true
PWP__MAIL__SMTP_ADDRESS=smtp.gmail.com
PWP__MAIL__SMTP_PORT=587
PWP__MAIL__SMTP_AUTHENTICATION=plain
PWP__MAIL__SMTP_USER_NAME=your-email@gmail.com
PWP__MAIL__SMTP_PASSWORD=your-app-specific-password
PWP__MAIL__SMTP_ENABLE_STARTTLS_AUTO=true
Setup Steps:
- Enable 2-Step Verification: Google Account Security
- Generate App Password: App Passwords
- Use the generated password in your configuration
Microsoft 365 / Exchange Online
Microsoft 365 requires login authentication (not plain).
mail:
raise_delivery_errors: true
smtp_address: 'smtp.office365.com'
smtp_user_name: 'your-email@domain.com'
smtp_password: 'your-password'
smtp_port: '587'
smtp_authentication: 'login' # Important: use 'login'
smtp_starttls: true
smtp_enable_starttls_auto: true
smtp_open_timeout: 10
smtp_read_timeout: 10
mailer_sender: '"Password Pusher" <your-email@domain.com>'
Environment Variables:
PWP__MAIL__RAISE_DELIVERY_ERRORS=true
PWP__MAIL__SMTP_ADDRESS=smtp.office365.com
PWP__MAIL__SMTP_PORT=587
PWP__MAIL__SMTP_AUTHENTICATION=login
PWP__MAIL__SMTP_USER_NAME=your-email@domain.com
PWP__MAIL__SMTP_PASSWORD=your-password
PWP__MAIL__SMTP_STARTTLS=true
PWP__MAIL__SMTP_ENABLE_STARTTLS_AUTO=true
Note: The smtp_domain setting is optional and can be omitted.
SendGrid
SendGrid uses an API key as the password with username apikey.
mail:
raise_delivery_errors: true
smtp_address: smtp.sendgrid.net
smtp_port: 587
smtp_authentication: plain
smtp_user_name: apikey
smtp_password: <your-sendgrid-api-key>
smtp_starttls: true
smtp_enable_starttls_auto: true
smtp_open_timeout: 10
smtp_read_timeout: 10
mailer_sender: '"Your Name" <name@domain.com>'
Environment Variables:
PWP__MAIL__RAISE_DELIVERY_ERRORS=true
PWP__MAIL__SMTP_ADDRESS=smtp.sendgrid.net
PWP__MAIL__SMTP_PORT=587
PWP__MAIL__SMTP_AUTHENTICATION=plain
PWP__MAIL__SMTP_USER_NAME=apikey
PWP__MAIL__SMTP_PASSWORD=your-sendgrid-api-key
PWP__MAIL__SMTP_STARTTLS=true
PWP__MAIL__SMTP_ENABLE_STARTTLS_AUTO=true
Amazon SES
Amazon SES requires specific configuration for SMTP.
mail:
raise_delivery_errors: true
smtp_address: email-smtp.<region>.amazonaws.com # e.g., email-smtp.us-east-1.amazonaws.com
smtp_port: 587
smtp_authentication: plain
smtp_user_name: <your-ses-smtp-username>
smtp_password: <your-ses-smtp-password>
smtp_starttls: true
smtp_enable_starttls_auto: true
smtp_open_timeout: 10
smtp_read_timeout: 10
Note: Amazon SES requires verification of sender email addresses and domains. See Amazon SES Documentation.
Configuration Methods
Using Environment Variables (Recommended)
Environment variables are the easiest method for Docker deployments:
Docker Compose:
services:
pwpush:
environment:
PWP__MAIL__RAISE_DELIVERY_ERRORS: 'true'
PWP__MAIL__SMTP_ADDRESS: 'smtp.example.com'
PWP__MAIL__SMTP_PORT: '587'
PWP__MAIL__SMTP_AUTHENTICATION: 'plain'
PWP__MAIL__SMTP_USER_NAME: 'username'
PWP__MAIL__SMTP_PASSWORD: 'password'
PWP__MAIL__SMTP_STARTTLS: 'true'
Docker Run:
docker run -d \
-e PWP__MAIL__RAISE_DELIVERY_ERRORS=true \
-e PWP__MAIL__SMTP_ADDRESS=smtp.example.com \
-e PWP__MAIL__SMTP_PORT=587 \
-e PWP__MAIL__SMTP_AUTHENTICATION=plain \
-e PWP__MAIL__SMTP_USER_NAME=username \
-e PWP__MAIL__SMTP_PASSWORD=password \
pglombardo/pwpush:stable
Using .env File
For better security and organization, use a .env file:
# .env file
PWP__MAIL__RAISE_DELIVERY_ERRORS=true
PWP__MAIL__SMTP_ADDRESS=smtp.example.com
PWP__MAIL__SMTP_PORT=587
PWP__MAIL__SMTP_AUTHENTICATION=plain
PWP__MAIL__SMTP_USER_NAME=username
PWP__MAIL__SMTP_PASSWORD=password
Docker Compose:
services:
pwpush:
env_file:
- .env
Docker Run:
docker run -d --env-file .env pglombardo/pwpush:stable
Using settings.yml
For more complex configurations, use a custom settings.yml file:
mail:
raise_delivery_errors: true
smtp_address: smtp.example.com
smtp_port: 587
smtp_authentication: plain
smtp_user_name: username
smtp_password: password
smtp_starttls: true
smtp_enable_starttls_auto: true
smtp_open_timeout: 10
smtp_read_timeout: 10
Mount it into the container:
volumes:
- type: bind
source: ./settings.yml
target: /opt/PasswordPusher/config/settings.yml
For more information, see Overlaying Files in Docker Containers.
Example Success Output
When a test email is sent successfully, you’ll see output like this:
╰─ docker compose exec pwpush bin/pwpush console
Password Pusher Version: 1.39.8
Loading production environment (Rails 7.1.3.2)
[1] pry(main)> TestMailer.send_test_email('user@example.com').deliver_now
--> Configured FROM: address: '"Password Pusher" <noreply@example.com>'
--> raise_delivery_errors is set to true in the configuration. This will raise an error if the email fails to send.
--> Attempting to send a test email to user@example.com...
--> It seems that the Email sent successfully! Check destination inbox for the test email.
--> If you see an error, please paste this output into a GitHub issue for help.
--> Make sure that no sensitive data is included.
--> https://github.com/pglombardo/PasswordPusher/issues/new/choose
TestMailer#send_test_email: processed outbound mail in 15.6ms
Delivered mail 6615a15c85a96_6c3b170c6251@host.local.mail (5413.4ms)
Date: Tue, 09 Apr 2024 22:13:16 +0200
From: Password Pusher <noreply@example.com>
To: user@example.com
Message-ID: <6615a15c85a96_6c3b170c6251@host.local.mail>
Subject: Test Email from Password Pusher
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
✅ If you are reading this, sending email works! ✅
=> #<Mail::Message:25660, Multipart: false, Headers: <Date: Tue, 09 Apr 2024 22:13:16 +0200>,
<From: "Password Pusher" <noreply@example.com>>, <To: user@example.com>,
<Message-ID: <6615a15c85a96_6c3b170c6251@host.local.mail>>,
<Subject: Test Email from Password Pusher>, <Mime-Version: 1.0>,
<Content-Type: text/plain>, <Content-Transfer-Encoding: quoted-printable>>
[2] pry(main)>
Troubleshooting Checklist
Use this checklist to systematically diagnose email issues:
- Enable error reporting: Set
PWP__MAIL__RAISE_DELIVERY_ERRORS=true - Verify SMTP server address: Check DNS resolution and connectivity
- Check port number: Verify port 587, 465, or 25 matches your server
- Verify authentication: Ensure username and password are correct
- Check authentication method: Use
plain,login, orcram_md5as required - Test STARTTLS: Try enabling/disabling STARTTLS settings
- Check timeouts: Increase timeout values if connections are slow
- Verify sender address: Ensure
mailer_sendermatches SMTP account - Test from console: Use
TestMailer.send_test_emailto get detailed errors - Check firewall: Ensure outbound SMTP connections are allowed
- Review server logs: Check SMTP server logs for rejection reasons
- Restart container: Restart after configuration changes
Getting Additional Help
If you’ve gone through this guide and are still experiencing issues:
-
Search existing issues: Check GitHub issues for similar problems and solutions
- Gather diagnostic information:
- Output from
TestMailer.send_test_email - Output from
Rails.application.config.action_mailer.smtp_settings(with sensitive data removed) - Container logs:
docker compose logs pwpush - SMTP server address, port, and authentication method
- Output from
- File a new issue: Create a GitHub issue with:
- Description of the problem
- Error messages (with sensitive data removed)
- SMTP configuration (with credentials removed)
- Steps to reproduce
Security Reminder: Never share passwords, API keys, or other sensitive credentials in issues, logs, or public forums.
See Also
- Configuration Strategies - Comprehensive configuration guide
- Self-Hosted Configuration - SMTP configuration for logins
- Application Console - How to access the console for testing
- Docker Environment File - Using .env files for configuration
- Overlaying Files - Using custom settings.yml files