C# – SmtpException: Unable to read data from the transport connection: net_io_connectionclosed

csmtp

I am using the SmtpClient library to send emails using the following:

SmtpClient client = new SmtpClient();
client.Host = "hostname";
client.Port = 465;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.EnableSsl = true;
client.Credentials = new NetworkCredential("User", "Pass);
client.Send("from@hostname", "to@hostname", "Subject", "Body");

The code works fine in my test environment, but when I use production SMTP servers, the code fails with an SmtpException "Failure sending mail." with an inner IOException "Unable to read data from the transport connection: net_io_connectionclosed".

I've confirmed that firewalls are not an issue. The port opens just fine between the client and the server. I'm not sure what else could throw this error.

Best Answer

EDIT: Super Redux Version

Try port 587 instead of 465. Port 465 is technically deprecated.


After a bunch of packet sniffing I figured it out. First, here's the short answer:

The .NET SmtpClient only supports encryption via STARTTLS. If the EnableSsl flag is set, the server must respond to EHLO with a STARTTLS, otherwise it will throw an exception. See the MSDN documentation for more details.

Second, a quick SMTP history lesson for those who stumble upon this problem in the future:

Back in the day, when services wanted to also offer encryption they were assigned a different port number, and on that port number they immediately initiated an SSL connection. As time went on they realized it was silly to waste two port numbers for one service and they devised a way for services to allow plaintext and encryption on the same port using STARTTLS. Communication would start using plaintext, then use the STARTTLS command to upgrade to an encrypted connection. STARTTLS became the standard for SMTP encryption. Unfortunately, as it always happens when a new standard is implemented, there is a hodgepodge of compatibility with all the clients and servers out there.

In my case, my user was trying to connect the software to a server that was forcing an immediate SSL connection, which is the legacy method that is not supported by Microsoft in .NET.