Unable to send an email via my SMTP server via SSL/TLS. But my local email client works well

I have my own SMTP server. It’s behind SSL/TLS - port 465

In my phoenix I use Swoosh to send emails. Since recently I’ve been facing this error:

delivery error:
{:retries_exceeded, {:network_failure, ~c"mail.my_mail_server.com", {:error, {:options, :incompatible, [verify: :verify_peer, cacerts: :undefined]}}}}

My config:

adapter: Swoosh.Adapters.SMTP,
    relay: host,
    username: user,
    password: password,
    port: port,

    ssl: true,
    tls: :always,

    # allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2", :"tlsv1.3"],
    auth: :always,
    retries: 5,
    no_mx_lookups: true,

    ssl: [
    # ssl_opts: [
    # ssl_options: [

        verify: :verify_none,
      # verify: :verify_peer,

      # cacerts: :public_key.cacerts_get(),
      # versions: [:"tlsv1.2"],
      # versions: [:"tlsv1.3"],
      #   customize_hostname_check: [
      #     match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
      #   ]

    tls_options: [
        # verify: :verify_peer,
        verify: :verify_none,

        # cacerts: :certifi.cacerts(),
        # cacerts: :public_key.cacerts_get(),
        #   server_name_indication: ~c"#{host}",

An interesting thing is that all the options that have to do with tls and ssl will be ignored.

Meaning, the error will always contain

<...> { verify: :verify_peer, cacerts: :undefined}...

There’s never been an error with verify: :verify_none and cacerts: <something_else>, even though I’ve set it up.

Why? I’ve set different values in the config. Why will they remain verify: :verify_peer, cacerts: :undefined ?

And it’s unclear wether I should used ssl_opts, ssl or ssl_options – I’ve tried dozens of combinations. The same goes for the tls_options.

What’s the matter?

The emails I’ll send from an email-client from my local computer via the same email server get sent with no issue, and under the same settings: port 465, SSL/TLS, same relay.


OTP 26.

I’m aware of this - Erlang/OTP 26 Highlights - Erlang/OTP

But, as I’ve mentioned, it’ll ignore my verify: <...> variables in the first place.

I had an issue similar to yours, and got it working with the following configuration:

config :messenger, Messenger.Mailer,
    sockopts: [
      cacerts: :public_key.cacerts_get(),
      customize_hostname_check: [
        match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
    adapter: Swoosh.Adapters.SMTP,
    relay: "smtp-relay.gmail.com",
    username: "no-reply@colecao.moda",
    tls: :never,
    ssl: true,
    auth: :always,
    retries: 2,
    no_mx_lookups: false,
    sockopts: [
      versions: [:"tlsv1.2", :"tlsv1.3"],
      verify: :verify_peer,
      depth: 99,
      server_name_indication: 'smtp-relay.gmail.com'

I am assuming you are using STARTTLS on port 465 with a self signed certificate
You have 2 ssl keys in the config, and it should be set to false. for details. see the official swoosh doc:


Yours is different, isn’t it? You use tls: :never

Why sockopts 2 times?

Where 2 ssl keys? What set to false? Why?


With STARTTLS you should omit the ssl configuration or set it to false.

In my case it’s not STARTTLS - it’s SSL/TLS

The :tls setting is for STARTTLS. If you’re not using starttls you should disable it. You can find a bit more context about that here: SSL connection options · Issue #298 · gen-smtp/gen_smtp · GitHub

tls: :never,


[notice] TLS :client: In state :wait_cert_cr at ssl_handshake.erl:2140 generated CLIENT ALERT: Fatal - Handshake Failure
 - {:bad_cert, :max_path_length_reached}

You have one line as ssl: true, and one as ssl: [ ...