Amazon SES SMTP with Django
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Amazon SES works well with Django because Django already knows how to send mail through any standard SMTP server. The important part is configuring SES correctly: verify identities, get region-specific SMTP credentials, and point Django at the right SMTP endpoint.
Prepare SES Before Touching Django
A Django setting alone is not enough. In SES, you need three things first:
- A verified sender identity, usually a domain or specific email address.
- SMTP credentials created for the SES SMTP interface.
- Production access if your account is still in the SES sandbox.
SES SMTP credentials are not the same as a normal AWS access key in the way you use them. AWS provides a dedicated SMTP username and password flow, and those credentials are region-specific. That means the hostname and credentials for us-east-1 are different from what you would use in another region.
A common SMTP host looks like this:
For Django, the usual port choices are:
- '
587with STARTTLS' - '
465with SSL'
Port 587 with TLS is the most common setup.
Configure Django Settings
Keep credentials out of source control. Read them from environment variables instead of hard-coding them in settings.py.
Example environment values:
If you are using a deployment platform, map those values into its secret manager rather than exporting them manually on every boot.
Send a Test Email
Once settings are in place, use Django’s mail API:
You can also test interactively:
If the app raises SMTPAuthenticationError, check the region, username, and password first.
Sending HTML Email
Transactional mail usually needs both text and HTML versions. Django supports that directly:
SES will accept the message over SMTP, but deliverability still depends on domain setup. In production, you should configure SPF, DKIM, and ideally DMARC for the sending domain.
Troubleshooting Real Failures
Two issues cause most SES and Django setup failures.
The first is sandbox mode. In the SES sandbox, you can only send to verified recipients. If mail succeeds in development but only to certain addresses, this is usually why.
The second is a region mismatch. Suppose your SMTP credentials were created in us-east-1, but Django is pointed at an endpoint in eu-west-1. Authentication will fail even if the username and password look correct.
Another useful check is connection security. Do not set both EMAIL_USE_TLS and EMAIL_USE_SSL to True. Pick the mode that matches the port you are using.
Common Pitfalls
Many developers assume SES SMTP uses their everyday AWS console login. It does not. Use SMTP credentials generated for SES.
Another mistake is forgetting identity verification. SES can reject mail from an address or domain that has not been verified, even though the SMTP connection itself works.
Hard-coding secrets in settings.py is also a bad habit. It creates rotation pain and increases the chance of leaking credentials.
Finally, do not stop at “email sent successfully” in application logs. Check SES metrics, bounce handling, and domain authentication records if delivery quality matters.
Summary
- Django can use Amazon SES through the standard SMTP backend.
- Verify the sender identity and create SES SMTP credentials first.
- Use the region-specific SES SMTP hostname and matching credentials.
- Store credentials in environment variables, not in source files.
- Watch for sandbox restrictions, region mismatches, and TLS configuration errors.

