Debugging Email Delivery Failures: Gmail Alias SMTP Relay vs. SES API Infrastructure
During a recent development session, we identified and diagnosed two distinct email delivery failures affecting the JADA sailing platform's proposal notification system. Both failures appeared in the same email thread but originated from completely different infrastructure layers. This post walks through the diagnostic approach and technical findings.
The Symptoms
Three outbound emails failed to deliver, with bounce messages returning to jadasailing@gmail.com. The error indicated "misconfigured or out of date" SMTP credentials. At first glance, this appeared to be a single SES configuration issue, but the root cause analysis revealed two independent failures:
- Failure 1: Gmail's "Send mail as" alias for
admin@queenofsandiego.comhad stale SMTP credentials - Failure 2: A separately-sent email via the SES API was rejected by the recipient's mail server (Exchange Online)
Technical Investigation: Failure 1 (Gmail SMTP Relay)
Gmail's "Send mail as" feature allows users to send from verified aliases by relaying through an external SMTP server. In this case, someone had configured admin@queenofsandiego.com as a send-as alias, pointing to our SES SMTP endpoint in us-east-1.
The diagnostic steps:
# Verify SES SMTP endpoint availability
aws ses describe-configuration-set --configuration-set-name [set-name] --region us-east-1
# Check current IAM credentials and derive SES SMTP password
# SES SMTP passwords are NOT the same as IAM access keys
# They must be derived using AWS Signature Version 4
SES SMTP credentials are derived from IAM access keys using the AWS Signature Version 4 algorithm, not stored directly in AWS. The process:
- Take the IAM secret access key
- Create a canonical string:
AWS4+aws4_request - Sign with the date and region (
us-east-1) - The final signature becomes the SMTP password
If IAM credentials are rotated, previously-configured Gmail aliases will fail unless the new SES SMTP credentials are regenerated and updated in Gmail settings.
Technical Investigation: Failure 2 (SES API Delivery Rejection)
While investigating Failure 1, we discovered a separate email had been sent via the SES API (not the Gmail alias) and was rejected by the recipient's mail server. This required validating the entire email infrastructure:
# Verify domain identity status
aws ses get-identity-verification-attributes \
--identities admin@queenofsandiego.com \
--region us-east-1
# Check DKIM configuration
aws ses verify-domain-dkim --domain queenofsandiego.com --region us-east-1
# List all DKIM tokens and verify CNAMEs in Route53
aws route53 list-resource-record-sets --hosted-zone-id [zone-id] \
--query "ResourceRecordSets[?Type=='CNAME']"
# Validate SPF and DMARC records
dig queenofsandiego.com TXT +short
dig _dmarc.queenofsandiego.com TXT +short
# Check suppression list for bounces/complaints
aws ses list-suppressed-destinations \
--reason Bounce \
--region us-east-1
The infrastructure validation showed:
- DKIM: All three DKIM CNAME records properly configured in Route53
- SPF: SPF record present with SES SMTP endpoints authorized
- DMARC: DMARC policy configured at
_dmarc.queenofsandiego.com - Custom MAIL FROM: Bounce and complaint addresses configured on the domain identity
- Suppression List: No problematic addresses in the us-east-1 suppression list
The SES infrastructure itself was clean. The rejection came from the recipient's Exchange Online mail server — a downstream issue outside our control.
Root Cause Analysis
Failure 1 Root Cause: The admin@queenofsandiego.com alias in jadasailing@gmail.com contained outdated SMTP credentials. These were likely set up months earlier pointing to:
Server: email-smtp.us-east-1.amazonaws.com
Port: 587 (TLS)
Username: [SES SMTP username derived from old IAM credentials]
When the underlying IAM credentials were rotated (as part of standard security practices), the derived SES SMTP password changed. Gmail continued using the old credentials, resulting in "misconfigured or out of date" errors.
Failure 2 Root Cause: The email sent via SES API passed all SMTP validation and left our infrastructure correctly. The rejection occurred at the recipient's mail server, indicating either:
- Recipient address was invalid or no longer monitored
- Recipient's mail server applied reputation filtering
- Message content triggered recipient-side spam filters
Solution and Prevention
For Failure 1: Regenerate SES SMTP credentials in the AWS console under SES → SMTP Settings, then update the Gmail alias configuration:
Gmail Settings → Accounts and Import → Send mail as
→ Edit admin@queenofsandiego.com
→ Update SMTP username and password
→ Test connection
For Failure 2: The SES infrastructure is properly configured. Validate recipient addresses before sending and monitor the suppression list for complaints:
# Monitor suppression list growth
aws ses list-suppressed-destinations \
--reason Complaint \
--region us-east-1 | jq '.SuppressedDestinationSummaries | length'
# Check specific address
aws ses list-suppressed-destinations \
--reason Complaint \
--region us-east-1 | grep "specific@domain.com"
Key Decisions
We chose to validate the entire SES infrastructure rather than assume Gmail's error message was the only issue. This revealed that our domain authentication, DKIM signing, and suppression handling were all correct — the problem was at the application (Gmail alias) layer and the recipient's server, not our email infrastructure.
This investigation pattern — validate infrastructure first, then work backward to application configuration — prevents false assumptions and saves debugging time when multiple systems interact.
What's Next
Implement automated credential rotation for SES SMTP credentials with alerting when Gmail relay authentication fails. Consider storing current valid SMTP credentials in AWS Secrets Manager or similar, with documented procedures for updating application-layer configuration when they rotate.
```