Debugging Multi-Layer Email Delivery Failures: Gmail SMTP Relay vs. SES API Authentication

Last week, three outbound emails from the JADA sailing platform failed to deliver, and the root cause wasn't singular—it involved two distinct failure modes across different sending mechanisms. This post walks through the systematic diagnosis process and the infrastructure decisions that led us here.

The Symptom

Three emails sent to external recipients bounced with vague error messages in Gmail's activity logs. The sender appeared to be admin@queenofsandiego.com, but the bounce notifications arrived at jadasailing@gmail.com. This asymmetry was the first clue that we were dealing with a Gmail "Send mail as" alias problem rather than a pure SES issue.

Architecture: How Email Leaves JADA

Our platform uses two distinct email sending paths:

  • Path A (Manual/Ad-hoc): Gmail's "Send mail as" feature in jadasailing@gmail.com, configured to relay through SES SMTP server at email-smtp.us-east-1.amazonaws.com on port 587 with TLS.
  • Path B (Automated/Campaigns): Lambda functions in us-west-2 invoking SES API directly using IAM credentials, for blast campaigns stored in S3 at s3://jada-blast-assets/campaigns/.

This dual-path architecture exists because manual sends from Gmail require human interaction (composing, reviewing), while campaign blasts are fully automated. The infrastructure separation meant we could isolate which path was failing.

Diagnostic Process: Layer-by-Layer Verification

Step 1: DNS and DKIM Verification

Before assuming credential issues, we validated the email infrastructure:


# Verify all 3 DKIM CNAME records exist in Route53
dig DKIM1._domainkey.queenofsandiego.com CNAME
dig DKIM2._domainkey.queenofsandiego.com CNAME
dig DKIM3._domainkey.queenofsandiego.com CNAME

# Check SPF record
dig queenofsandiego.com TXT | grep "v=spf1"

# Check DMARC policy
dig _dmarc.queenofsandiego.com TXT

# Verify custom MAIL FROM domain
dig mail.queenofsandiego.com MX

Result: All DNS records were correctly configured. DKIM, SPF, and DMARC were properly set up with custom MAIL FROM domain mail.queenofsandiego.com. This ruled out authentication-level rejection at recipient domains.

Step 2: SES Account Status and Suppression List

We checked whether the sending identity was in AWS SES's suppression list or had other account-level restrictions:


# List all verified SES identities with verification status
aws ses list-verified-email-addresses --region us-east-1

# Get full identity details
aws ses get-identity-attributes \
  --identities admin@queenofsandiego.com \
  --region us-east-1

# Check suppression list entries
aws sesv2 get-suppressed-destination \
  --email-address admin@queenofsandiego.com \
  --region us-east-1

Result: admin@queenofsandiego.com was verified and had no suppression entries in us-east-1. However, we discovered evastarr24@... had complaint-based suppressions in us-west-2, which was unrelated to this incident but noted for separate remediation.

Step 3: SMTP Credential Derivation and Testing

For Path A (Gmail relay), we needed to verify that the SES SMTP credentials in Gmail's configuration were valid. SES SMTP passwords are derived from IAM credentials using AWS's SigV4 algorithm:


# Get current IAM user information
aws iam get-user

# Derive SES SMTP password from access key
# (Using official AWS SigV4 derivation, not shown for security)
# This produces a 64-character encrypted password

# Test SMTP connectivity
openssl s_client -connect email-smtp.us-east-1.amazonaws.com:587 -starttls smtp
# Then AUTH LOGIN with derived credentials

Result: The derived SES SMTP credentials were valid and authentication succeeded. This meant the current IAM access key could successfully authenticate to SES SMTP.

Root Cause Analysis: Two Separate Failures

Failure Mode 1: Gmail "Send mail as" Configuration (Path A)

Gmail stores SMTP credentials for "Send mail as" aliases at Settings → Accounts and Import → Send mail as. These credentials are encrypted and stored in Gmail's servers. When Gmail attempts to relay an email through the configured SMTP server, it uses these stored credentials.

The problem: The SMTP credentials stored in Gmail's "Send mail as" configuration for admin@queenofsandiego.com are either:

  • Expired or rotated (if SES SMTP credentials were regenerated in AWS without updating Gmail)
  • Never properly verified (if the alias was added without completing the SMTP test in Gmail's setup flow)
  • Pointing to the wrong SES endpoint region

Gmail's error message "misconfigured or out of date" is accurate but not specific enough to pinpoint which of these occurred.

Why the bounce came to jadasailing@gmail.com: Gmail knows that the real sending account is jadasailing@gmail.com (the account actually using the alias), so bounce notifications return to the real account, not the alias.

Failure Mode 2: Recipient Domain Rejection (Path B)

For emails that did successfully leave SES via API path, some were rejected at the recipient's mail server. Specifically, emails to recipients at steigerwald-dougherty.com were being rejected by Microsoft Exchange Online.


# Check recipient domain MX records
dig steigerwald-dougherty.com MX

# Verify custom MAIL FROM domain bounce reputation
aws sesv2 get-deliverability-dashboard-options --region us-east-1

Root cause: The custom MAIL FROM domain mail.queenofsandiego.com likely has a low reputation score or lacks proper SPF/DKIM alignment at that recipient's servers. This is not a JADA configuration issue but rather a domain reputation issue requiring time and clean sends to remediate.

Key Infrastructure Decisions

Why we maintain dual email paths: Gmail's SMTP relay is human-operated and provides a UX for manual composition. SES API is fully automated and scales to thousands of sends. Coupling them would require building a webmail interface or email composition service—not worth the complexity.

Why we use us-east-1 for SMTP but us-west-2 for Lambda: The Gmail configuration historically pointed to us-east-1 (where the JADA AWS account's primary SES setup was done). Lambda functions in us-west-2 use local region endpoints for lower latency to our Lightsail instances, which are also in us-west-2.

Why custom MAIL FROM is necessary: Using the SES default bounce domain (bounce