emailsslelixirphoenix-frameworkamazon-ses

Simply sending email with Elixir Phoenix via Amazon SES but cacerts undefined


I suspect the problem is that I simply can't find a working example of how to configure Amazon SES config for Elixir / Phoenix.

The problem seems to be cacerts: :undefined.

export SES_SMTP_SERVER=email-smtp.us-west-1.amazonaws.com
export SES_SMTP_PORT=465
export SES_SMTP_USERNAME=redacted
export SES_SMTP_PASSWORD=redacted

Here's my config/prod.exs:

config :my_app, MyApp.Mailer,
  adapter: Bamboo.SMTPAdapter,
  server: System.get_env("SES_SMTP_SERVER") || "email-smtp.us-east-1.amazonaws.com",
  port: String.to_integer(System.get_env("SES_SMTP_PORT") || "587"),
  username: System.get_env("SES_SMTP_USERNAME"),
  password: System.get_env("SES_SMTP_PASSWORD"),
  tls: :always,
  tls_cacertfile: "/etc/ssl/certs/ca-certificates.crt",
  ssl: true,
  retries: 1,
  ssl_options: [
    verify: :verify_peer,
    cacertfile: "/etc/ssl/certs/ca-certificates.crt"
  ]

Here's the error that I'm getting when I try to send email:

Failed to send email.
Reason: {:network_failure, ~c"54.176.126.9", {:error, {:options, :incompatible, [verify: :verify_peer, cacerts: :undefined]}}}

It sounds like it can't find the SSL / TLS (?) certificate file. I've run apt-get install ca-certificates to no avail, same error message.

I've looked up the docs for Bamboo.SMTPAdapter [1] but there's no hint on how to specify the SSL certificate.

Has anyone successfully sent email from Phoenix in production?

For context, I encountered a similar error when trying to send email via Gmail with Elixir / Phoenix: Phoenix / Elixir: Sending email via Gmail certificate error

Update: I started with Swoosh, switched to Bamboo, neither work, so my question is: what is the underlying problem?

[1] https://hexdocs.pm/bamboo_smtp/Bamboo.SMTPAdapter.html


Solution

  • I managed to get it working. With Swoosh SMTPAdapter, without using Mua.

    Here is my working config for sending email from Elixir Phoenix with Amazon SES in 2024:

    smtp_relay =                                                                                                          
        System.get_env("SES_SMTP_SERVER")                                                                                 
        |> to_charlist()                                                                                                  
                                                                                                                          
    config :my_app, MyApp.Mailer,                                                                                    
      adapter: Swoosh.Adapters.SMTP,                                                                                      
      relay: System.get_env("SES_SMTP_SERVER") || "email-smtp.us-east-1.amazonaws.com",                                   
      port: String.to_integer(System.get_env("SES_SMTP_PORT") || "587"),                                                  
      username: System.get_env("SES_SMTP_USERNAME"),                                                                      
      password: System.get_env("SES_SMTP_PASSWORD"),                                                                      
      tls: :always,                                                                                                       
      auth: :always,                                                                                                      
      ssl: false,  # true if using port 465                                                                               
      tls_options: [                                                                                                      
          verify: :verify_peer,                                                                                           
          middlebox_comp_mode: false, # <--- this is required!                                                         
          # cacerts: :certifi.cacerts(),
          cacerts: :public_key.cacerts_get(),                                                                             
          server_name_indication: smtp_relay, # <--- this is required!                                                    
          depth: 99,                                                                                                      
          log_level: :debug                                                                                               
        ]                                                                                                                 
    

    I also ran into an auth_failed error, which was caused by using the Amazon SES username (incorrect), instead of the randomly generated SMTP username and password from the Amazon SES setup page.

    Good luck all, even to the downvoters.