Asp.net Send Email Using Tls Example
Ever since I posted a quick guide to sending email via Mailkit in .NET Core 2, I have been inundated with comments and emails asking about specific exception messages that either Mailkit or the underlying .NET Core. Rather than replying to each individual email, I would try and collate all the errors with sending emails here. It won't be pretty to read, but hopefully if you've landed here from a search engine, this post will be able to resolve your issue.
I should also note that the solution to our "errors" is usually going to be a change in the way we use the library MailKit. If you are using your own mail library (Or worse, trying to open the TCP ports yourself and manage the connections), you will need to sort of "translate" the fix to be applicable within your code.
Let's go!
Default Ports
Before we go any further, it's worth noting the "default" ports that SMTP is likely to use, and the settings that go along with them.
Port 25
25 is typically used a clear text SMTP port. Usually when you have SMTP running on port 25, there is no SSL and no TLS. So set your email client accordingly.
Port 465
465 is usually used for SMTP over SSL, so you will need to have settings that reflect that. However it does not use TLS.
Port 587
587 is usually used for SMTP when using TLS. TLS is not the same as SSL. Typically anything where you need to set SSL to be on or off should be set to off. This includes any setting that goes along the lines of "SSLOnConnect". It doesn't mean TLS is less secure, it's just a different way of creating the connection. Instead of SSL being used straight away, the secure connection is "negotiated" after connection.
Settings that are relevant to port 587 usually go along the lines of "StartTLS" or simply "TLS". Something like Mailkit usually handles TLS for you so you shouldn't need to do anything extra.
Incorrect SMTP Host
System.Net.Sockets.SocketException: No such host is known
This one is an easy fix. It means that you have used an incorrect SMTP hostname (Usually just a typo). So for example using smp.gmail.com instead of smtp.gmail.com. It should be noted that it isn't indicative that the port is wrong, only the host. See the next error for port issues!
Incorrect SMTP Port
System.Net.Internals.SocketExceptionFactory+ExtendedSocketException: A socket operation was attempted to an unreachable network [IpAddress]:[Port]
Another rather simple one to fix. This message almost always indicates you are connecting to a port that isn't open. It's important to distinguish that it's not that you are connecting with SSL to a non SSL port or anything along those lines, it's just an out and out completely wrong port.
It's important that when you log the exception message of this error, you check what port it actually says in the log. I can't tell you how many times I "thought" I was using a particular port, but as it turned out, somewhere in the code it was hardcoded to use a different port.
Another thing to note is that this error will manifest itsef as a "timeout". So if you try and send an email with an incorrect port, it might take about 30 seconds for the exception to actually surface. This is important to note if your system slows to a crawl as it gives you a hint of what the issue could be even before checking logs.
Forcing Non-SSL On An SSL Port
MailKit.Net.Smtp.SmtpProtocolException: The SMTP server has unexpectedly disconnected.
I want to point out this is a MailKit exception, not one from .NET. In my experience this exception usually pops up when you set Mailkit to not use SSL, but the port itself requires SSL.
As an example, when connecting to Gmail, the port 465 is used for SSL connections. If I try and connect to Gmail with the following Mailkit code :
var emailClient = new SmtpClient(); emailClient.Connect("smtp.gmail.com", 465, false); That last parameter that's set to false is telling Mailkit to not use SSL. And what do you know, we get the above exception. The easy fix is obviously to change this to "true".
Alternatively, you might be getting confused about TLS vs SSL. If the port says to connect using SSL, then you should not "force" any TLS connection.
Connecting Using SSL On A TLS Port (Sometimes)
MailKit.Security.SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection.
Another Mailkit specific exception. This one can be a bit confusing, especially because the full error log from MailKit talks about certificate issues (Which it totally could be!), but typically when I see people getting this one, it's because they are trying to use SSL when the port they are connecting to is for TLS. SSL != TLS.
So instead of trying to connect using MailKit by forcing SSL, just connect without passing in an SSL parameter.
emailClient.Connect("smtp.gmail.com", 465); I should note that you will also get this exception in Mailkit if you try and force the SSLOnConnect option on a TLS Port. So for example, the following will not work :
emailClient.Connect("smtp.gmail.com", 587, MailKit.Security.SecureSocketOptions.SslOnConnect); Again, sometimes this is because the SSL connection truly is bogus (Either because the certificate is bad, expired etc), or because you are connecting to a port with no security whatsoever. But because of the rise of TLS, I'm going to say the most likely scenario is that you are trying to force SSL on a TLS port.
Another error that you can sometimes get with a similar setup is :
Handshake failed due to an unexpected packet format
This is an exception that has a whole range of causes, but the most common is forcing an SSL connection on a TLS port. If your SMTP port supports "TLS", then do not set SSL to true.
Forcing No TLS On A TLS Port
System.NotSupportedException: The SMTP server does not support authentication.
This one is a little weird because you basically have to go right out of your way to get this exception. The only way I have seen this exception come up when you are telling Mailkit to go out of it's way to not respect any TLS messages it gets and try and ram authentication straight away.
So for example, the following code would cause an issue :
emailClient.Connect("smtp.gmail.com", 587, MailKit.Security.SecureSocketOptions.None); Incorrect Username And/Or Password
MailKit.Security.AuthenticationException: AuthenticationInvalidCredentials: 5.7.8 Username and Password not accepted.
Goes without saying, you have the wrong username and password. This is not going to be any connection issues. You definitely have the right host and port, and the right SSL/TLS settings, but your username/password combination is wrong.
Other Errors?
Have something else going haywire? Drop a comment below!
Learned Something New?
By buying me a coffee (As a one off or monthly), you ensure I have the optimal caffeine levels to continue reading patch notes and wading through shoddy documentation to give you nothing but the important bits of .NET.
Asp.net Send Email Using Tls Example
Source: https://dotnetcoretutorials.com/2018/03/18/common-errors-sending-email-mailkit/
0 Response to "Asp.net Send Email Using Tls Example"
Post a Comment