Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Amazon SES Stops Working

I set up Amazon SES and it initially worked for a few hours, then all of a sudden stopped. All of the e-mails I'm sending as, and our domain, have been verified. We are no sending bulk e-mails - only a few hundred per day. Whenever I make changes to the web.config it seems to allow it work again for another 2-3 hours. For example, It stopped working so I switched port 587 to 25, and it began working for 2-3 hours, then stopped. Then I switched back to 587 and the same thing happened. Once it stops working it doesn't ever seem to start again on its own. It is running on two load balanced servers, asp.net framework v2.0, IIS 7.5. Here is the code I'm using:

web.config:

<system.net>
  <mailSettings>
    <smtp deliveryMethod="Network" from="[email protected]">
      <network defaultCredentials="false" host="email-smtp.us-east-1.amazonaws.com" userName="***" password="***" port="587" />
    </smtp>
  </mailSettings>
</system.net>

c# code:

var smtpClient = new SmtpClient() { EnableSsl = true };

var mailMessage =
    new MailMessage(fromAddress, toAddress, subject, body)
    {
        IsBodyHtml = true
    };

smtpClient.Send(mailMessage);

Here are the two errors I've been receiving:

The following exception was thrown by the web event provider '(null)' in the application '/' (in an application lifetime a maximum of one exception will be logged per provider instance):

System.Web.HttpException: Unable to send out an e-mail to the SMTP server. Please ensure that the server specified in the <smtpMail> section is valid. ---> System.Net.Mail.SmtpException: Failure sending mail. ---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
   at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
   at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.Mail.SmtpConnection.Flush()
   at System.Net.Mail.ReadLinesCommand.Send(SmtpConnection conn)
   at System.Net.Mail.SmtpConnection.GetConnection(String host, Int32 port)
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   --- End of inner exception stack trace ---
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at System.Web.Management.MailWebEventProvider.SendMail(MailMessage msg)
   --- End of inner exception stack trace ---
   at System.Web.Management.MailWebEventProvider.SendMail(MailMessage msg)
   at System.Web.Management.SimpleMailWebEventProvider.SendMessageInternal(WebBaseEventCollection events, Int32 notificationSequence, Int32 begin, DateTime lastFlush, Int32 discardedSinceLastFlush, Int32 eventsInBuffer, Int32 messageSequence, Int32 messagesInNotification, Int32 eventsInNotification, Int32 eventsLostDueToMessageLimit)
   at System.Web.Management.SimpleMailWebEventProvider.SendMessage(WebBaseEvent eventRaised)
   at *****.Global.SimpleMailWithSslWebEventProvider.ProcessEvent(WebBaseEvent raisedEvent)
   at System.Web.Management.WebBaseEvent.RaiseInternal(WebBaseEvent eventRaised, ArrayList firingRuleInfos, Int32 index0, Int32 index1)

The following exception was thrown by the web event provider '(null)' in the application '/' (in an application lifetime a maximum of one exception will be logged per provider instance):

System.Web.HttpException: Unable to send out an e-mail to the SMTP server. Please ensure that the server specified in the <smtpMail> section is valid. ---> System.Net.Mail.SmtpException: Service not available, closing transmission channel. The server response was: Timeout waiting for data from client.
   at System.Net.Mail.MailCommand.CheckResponse(SmtpStatusCode statusCode, String response)
   at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, SmtpFailedRecipientException& exception)
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
   at System.Web.Management.MailWebEventProvider.SendMail(MailMessage msg)
   --- End of inner exception stack trace ---
   at System.Web.Management.MailWebEventProvider.SendMail(MailMessage msg)
   at System.Web.Management.SimpleMailWebEventProvider.SendMessageInternal(WebBaseEventCollection events, Int32 notificationSequence, Int32 begin, DateTime lastFlush, Int32 discardedSinceLastFlush, Int32 eventsInBuffer, Int32 messageSequence, Int32 messagesInNotification, Int32 eventsInNotification, Int32 eventsLostDueToMessageLimit)
   at System.Web.Management.SimpleMailWebEventProvider.SendMessage(WebBaseEvent eventRaised)
   at *****.Global.SimpleMailWithSslWebEventProvider.ProcessEvent(WebBaseEvent raisedEvent)
   at System.Web.Management.WebBaseEvent.RaiseInternal(WebBaseEvent eventRaised, ArrayList firingRuleInfos, Int32 index0, Int32 index1)

I tried to get help on the Amazon forums but haven't had any luck. It seems like something is interfering with the connection but I don't know what. Any ideas? Thanks.

like image 684
StronglyTyped Avatar asked Jan 28 '13 13:01

StronglyTyped


People also ask

Is AWS SES deprecated?

To enhance the security of Amazon SES customers, beginning October 1, 2020, support for Signature Version 3 will be turned off (deprecated) in Amazon SES, and only Signature Version 4 will be supported going forward.

How many emails can I send with Amazon SES?

When your account is in the Amazon SES sandbox, you can only send 200 messages per 24-hour period, and your maximum sending rate is one message per second. When you submit a request to have your account removed from the sandbox, you can also request that your quotas are increased at the same time.

Why am I not getting my emails from Amazon?

If you are no longer receiving these e-mails, you should make sure that: E-mail order notifications are still enabled in your Notification Preferences found in the Settings drop-down menu. You have received new orders since the e-mails stopped coming.

Can't connect to SMTP host SES?

If you can't connect to the Amazon SES SMTP endpoint using telnet or openssl , it indicates that something in your network (such as a firewall) is blocking outbound connections over the port you're trying to use. Work with your network administrator to diagnose and fix the problem.


1 Answers

This sounds like a tricky issue indeed - I'm not 100% positive on this, but you seem to miss disposing the SMTP client, which is mentioned in Sending email is often very slow after changing to VPC instance to cause the very error you are seeing:

When I do not dispose of the SmtpClient, I get the error...

'Service not available, closing transmission channel. The server response was: Timeout waiting for data from client.'

This would actually be a good explanation for intermittent problems, i.e. depending on the executed code path this issue could trigger the SMTP connection to Amazon SES to hang, which is obviously remedied by switching to another port, implying the connection being reset - that's what the SmtpClient.Dispose Method ensures as well:

Sends a QUIT message to the SMTP server, gracefully ends the TCP connection, and releases all resources used by the current instance of the SmtpClient class.

Accordingly, an appropriate pattern would be to facilitate a using Statement, as demonstrated in Getting Started with Amazon SES and .NET:

  String username = "SMTP-USERNAME";  // Replace with your SMTP username.
  String password = "SMTP-PASSWORD";  // Replace with your SMTP password.
  String host = "email-smtp.us-east-1.amazonaws.com";
  int port = 25;

  using (var client = new System.Net.Mail.SmtpClient(host, port))
  {
    client.Credentials = new System.Net.NetworkCredential(username, password);
    client.EnableSsl = true;

    client.Send
    (
              "[email protected]",  // Replace with the sender address.
              "[email protected]",    // Replace with the recipient address.
              "Testing Amazon SES through SMTP",              
              "This email was delivered through Amazon SES via the SMTP end point."
    );
  }

Please note that the sample is using port 25, which I highly recommend to avoid due to the usually implied sending restrictions, see Addendum below for details regarding the respective Amazon EC2 throttling.

Good luck!


Addendum

Amazon EC2 throttling on port 25

You are probably aware of this (and I actually don't think it's an issue here), but Amazon EC2 imposes default sending limits on email sent via port 25 and throttles outbound connections if you attempt to exceed those limits which still applies when using Amazon SES, see Amazon SES SMTP Issues:

You are sending to Amazon SES from an Amazon EC2 instance via port 25 and you cannot reach your Amazon SES sending limits or you are receiving time outs — Amazon SES EC2 imposes default sending limits on email sent via port 25 and throttles outbound connections if you attempt to exceed those limits. To remove these limits, submit a Request to Remove Email Sending Limitations. You can also connect to Amazon SES via port 465 or port 587, neither of which is throttled.

Consequently I'd remove port 25 out of your testing/switching scenario and use ports 465/587 only instead in order to avoid false leads (as quoted you could also request to get this limitation removed though, but it will take a few hours and port 25 seems to be best avoided in the first place) - it's a bit unfortunate that several official Amazon SES samples are using port 25 without even mentioning this easily triggered issue indeed.

like image 135
Steffen Opel Avatar answered Oct 13 '22 05:10

Steffen Opel