Debugging AWS SES templates

Stefan OlaruStefan Olaru
3 min read

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.

0
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.