Debugging AWS SES templates
AWS SES is extremely powerful but it's likely surpassed only by AWS Cognito in terms of opacity and debugging difficulty. It usually works, but when it doesn't, it's a time-sink.
I've been working on migrating a client's on-premise shopping cart solution to AWS, and one of the tasks was to refactor the email notifications feature to use AWS SES instead of Mailgun.
For transactional emails such as order confirmations, shipping notifications, or payment receipts the email templates work like magic, you set it and forget it.
Both Mailgun and AWS SES support email templates, they're based on the Handlebars template system and work pretty much the same, or at least they should.
The problem
Post migration all transactional emails are getting sent but not delivered to the inbox. No clue of what's happening, no errors whatsoever.
Debugging steps
I started to investigate the possible causes:
✅ the account is moved out of sandbox mode
✅ the sender's identity is verified
✅ the DKIM is set
✅
SendTemplatedEmailCommand
returns a successful message✅ sends count against Daily email usage in the SES dashboard
✅ checked the Spam folder, nothing
Everything looks fine, yet emails are not reaching the inbox.
I did a quick test with a one-line template and it works. Bingo! 🥳 So there's a problem with the email template rendering.
Ok, great, but how do I debug the AWS SES template? The syntax looks correct!
The solution
I quickly looked for some tools but didn't find anything meaningful, so went to the docs and found this CLI method aws sesv2 test-render-email-template
which saved my day!
You can use this command with the --template-name
and --template-data
parameters and get a preview of the email content or an error.
Of course, it was an email template rendering error and this is the only way I could figure it out.
An error occurred (BadRequestException) when calling the TestRenderEmailTemplate operation: Attribute 'tax_amount' is not present in the rendering data.
The error is misleading because the tax_amount
was present in my --template-data
but had a null
value for this specific case:
{
"id": "2cl7Nr9KoU2KvB8ADy0s1hnD111",
"customer_name": "Stefan Potter",
"currency": "USD",
"items":
[
{
"image": "https://path/to/images/product-1.jpg",
"quantity": 1,
"price": 89.00,
"name": "Wireless Headphones",
"description": "Simple product with available quantity.",
"id": "HEADPHONESX"
}
],
"shipping_address": "Behind Corner 5<br />Crater 12345<br />Moon",
"shipping_method": "flat",
"shipping_amount": 12.00,
"billing_method": "stripe",
"tax_amount": null,
"total_amount": 101.00
}
Replacing the value with 0
fixed the template rendering.
If the template data contains non-compliant variables (whatever that means) or is missing variables, then Amazon SES won't deliver the email, but it won't tell you specifically.
I later came across this warning buried deeply in the CLI docs:
However, if Amazon SES can't render the email because the template contains errors, it doesn't send the email. Additionally, because it already accepted the message, Amazon SES doesn't return a message stating that it was unable to send the email.
The recommended way to handle these sorts of issues is to configure Amazon SES to send Rendering Failure event notifications through Amazon SNS.
Subscribe to my newsletter
Read articles from Stefan Olaru directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Stefan Olaru
Stefan Olaru
An architect by trade, practicing architecture in the Cloud. 7x AWS Certified, AWS Community Builder, Serverless advocate, Vue enthusiast.