Skip to content

Instantly share code, notes, and snippets.

@grantpullen
Created December 5, 2019 06:05
Show Gist options
  • Save grantpullen/0e2d5ef960dfae70072e9d36b051c703 to your computer and use it in GitHub Desktop.
Save grantpullen/0e2d5ef960dfae70072e9d36b051c703 to your computer and use it in GitHub Desktop.
SMTP golang e-email troubleshooting

SMTP Ports and Troubleshooting in Go

SMTP Port Overview

  • Port 25: SMTP port 25 (RFC 821) is used for SMTP relay, where email is relayed email from email server to email server. This port is not supported by most modern email clients.

  • Port 465: Internet Assigned Numbers Authority (IANA), registered port 465 for SMTPS using SSL. The port was revoked a year later, and is not used by most modern mail servers since it's not RFC compliant.

  • Port 587: This port (RFC 2476) is the current "official" SMTP port, and can be used for insecure and secure communication. RFC 2487 specifies that the STARTTLS command can be used to upgrade the connection to TLS This is supported by most modern email providers.

Original E-mail Provider

The code was sending email vai smtp.office365.com on port 587 using the standard Go smtp library, as shown below:

a := smtp.PlainAuth("", "sender@example.com", "password", "smtp.example.com")
err := smtp.SendMail("smtp.example.com:587",
		a, "sender@example.com", []string{"someone@one.com"}, []byte(subject+mime+htmlBody))
}

Traditionally when TLS is supported by the email server it negotiates a new TLS session after connection to port 587

Troubleshooting New E-mail Provider on port 465

After moving to a different mail provider, which we were told to use port 465 we got the following error:

EOF

Switching to port 587 resulted in the following error:

Your FROM address ( example.com , ) must match your authenticated email domain ( example.com ). Treating this as a spoofed email.

After much investigation, it turns out that we had to use port 465, and immediately establish a TLS session. We did this via the nice SMTP library created by Jordan Wright github.com/jordan-wright/email

Sample working code below:

e := ml.NewEmail()
e.From = fmt.Sprintf("%s <%s>", "sender@example.com", "smtp.example.com")
e.To = []string{"someone@one.com"}
e.Subject = "subject"
e.Text = []byte("text body")
e.HTML = []byte("<b>html body</b>")
a := smtp.PlainAuth("", "sender@example.com", "password", "smtp.example.com")
t := &tls.Config{
	InsecureSkipVerify: false,
	ServerName:         "smtp.example.com",
}
	return e.SendWithTLS("smtp.example.com:468", a, t)

Conclusion

  • When using (unsupported) port 465, TLS must be forced.
  • When using a large email provider such as microsoft/google, port 587 will support STARTTLS, and the standard go SMTP calls can be easily used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment