I hate to just post a stack trace here, but I am out of ideas... My app sends emails for various tasks on the website, and 90% of the time there are no problems. However, every so often ASP.NET throws a weird exception, which seems to relate to mail server connectivity (I use google business servers for email). The error is too generic for me to debug, hence the stack trace below. My app captures the exception and writes back a generic 'try again in 5 minutes response'.
I'm stumped by this error because:
Google email is generally very reliable (it is being sent from my domain, not gmail.com).
Volumes are very low, so this shouldn't be a loading/spamming type of problem.
Error is very generic.
Trying again in 5 minutes almost always allows the email to be sent with no problem, with none of the parameters (recipient, subject, body) having changed.
Any ideas? The only outstanding issues I can think of is that:
Email sending is synchronous. This is what I actually want to occur, as I want to respond to the user with a success/failure status message.
I am using Amazon EC2 as a server, if that has any bearing on the matter.
The code:
public static void SendMail(String from, String to, String subject, String body, bool IsHtml)
{
MailMessage m = new MailMessage(from, to, subject, body);
m.IsBodyHtml = IsHtml;
SmtpClient smtpClient = new SmtpClient();
smtpClient.EnableSsl = true;
smtpClient.Send(m);
}
The exception:
System.Net.Mail.SmtpException: Error in processing. The server response was: 4.3.0 Mail server temporarily rejected message. m6sm2190005vcx.24
at System.Net.Mail.DataStopCommand.CheckResponse(SmtpStatusCode statusCode, String serverResponse)
at System.Net.Mail.DataStopCommand.Send(SmtpConnection conn)
at System.Net.Mail.SmtpConnection.OnClose(Object sender, EventArgs args)
at System.Net.ClosableStream.Close()
at System.Net.Mail.MailWriter.Close()
at System.Net.Mail.SmtpClient.Send(MailMessage message)
I've worked on bulk email systems in the past. The exception message you are getting is totally descriptive: that SMTP server is temporarily not accepting mail. This can be due to a number of conditions:
The server is busy
You are sending too many emails too fast (this can make you look like a spammer)
General errors
The fact that retrying the email later always works indicates that this is normal, expected behavior. There is nothing you can do differently to avoid this, it's a common method used by ISPs to throttle traffic when needed.
In addition to what Dave Swersky already said:
You could store the emails you want to send somewhere (like filesystem or database) and let the e-mail generation be handeld by a service. Your service would watch for new emails to send. If an error occurs while sending, you could put the e-mail back into the queue and try again later.
Maybe you can even use a local STMPServer that uses GoogleMail as relay server. It that case you could use the built-in pickupdirectory functionality instead of writing it yourself.
Related
I used Artalk XMPP nuget package in my C# application. I was able to send messages from the user account userA#domain.com to the user account userB#domain.com through Ignite OpenFire server on our LAN. There were several minor issues with the messages that are not showstoppers:
If I tried to provide a subject, it was prefixed with the word "Subject: " in the client. This is not a problem but I am wondering if this is a remote client or server thing.
The message body was wrapped in square brackets as [test message body]. This is not a big problem but I would rather avoid it, to preserve the message being sent as-is, for the possible automatic processing. Is this a remote client or server thing?
If message body contained XML, then it was sent successfully but never received. Is sending XML not allowed by XMPP protocol? Or is it a server or remote client thing?
Edit:
Since I asked the above bullet, I tried to use System.Security.SecurityElement.Escape() on the message body and wrapped it in <![CDATA[]]> and it was delievered with its XML preserved. The question still stands.
All successfully delivered messages have been also copied by userB back to userA. This is all right if userA is not interactive, but if it is also a real human being, then it may be annoying. Is this a server or remote client thing, and is there any way to avoid it? I know that the remote user's client does not do it with regular chat messages sent through a Jabber client to them.
Next, I had userB#domain.com invite userA#domain.com to a chat room conference.domain.com#conference.domain.com and tried to send messages to that chat room, still from userA#domain.com. No messages have been received in the conference room, and there was no exception thrown during the sending.
ArtalkXmppClient xmpp;
xmpp = new ArtalkXmppClient("domain.com", "userA#domain.com", "secret", 5222, true);
try
{
var msg = new Message(
"conference.domain.com#conference.domain.com",
"test message body",
"conference subject", // conference allows participants to change subject
null,
MessageType.Groupchat,
CultureInfo.CurrentCulture);
if (!xmpp.Connected)
{
xmpp.Connect("myapp");
}
xmpp.SendMessage(msg);
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
The solution to the group chat part of the question was to pre-create the group on the server before trying to send to it and to use MessageType.Chat.
The last part was counter-intuitive and I would have never figured it out, if I did not forget to enable group chat in the configuration during testing. When using MessageType.GroupChat or any type other than Chat it simply did not work.
Also, subject must be null, otherwise subject will change but no messages will be delivered. Changes of subject have to be sent on their own, separate messages without bodies.
The only side effect that I am noticing is that with group chat, as opposed to person-to-person chat, the messages appear escaped. I am not sure what escapes them as opposed to person-to-person chat, but this is kind of acceptable.
I have a server that runs IIS and PHP. I have numerous webpages that send emails, some to me, some to the users. This all works great. I am on a Comcast Business Class account which means I can use smtp.comcast.net as my SMTP server, use port 25, and not use any sort of authentication which is great. And it works just fine.
Now fast forward to today. I am writing some custom C# code to monitor a folder structure and basically email me the new file if it matches certain parameters. In my C# code, I try to use the same settings, but it doesn't work. The SmtpClient.Send() function does not throw an Exception and my code completes the routine as if everything is happy and working. But then I wait and wait and wait, and I never receive the email.
SmtpClient smtp = new SmtpClient("smtp.comcast.net");
smtp.Port = 25;
smtp.EnableSsl = false;
smtp.UseDefaultCredentials = false;
smtp.Timeout = 2500;
smtp.Send(mail);
onStatusUpdate("Successfully sent email to " + mail.To + (mail.CC.Count > 0 ? " and CC'd " + mail.CC.ToString() : ""));
The "mail" object is of type MailMessage and is setup with the To, From, subject, body, and CC. Also has HTML and Plain Text alternate views.
I guess the easiest question, is if there is a trick to sending email the oldschool port-25 way in C# that doesn't exist in PHP?
And the only reason I mention PHP is because I know my firewall isn't blocking port 25, I know my ISP has it open, I know I have the right server, I know it should work.
I don't know if this affects their Business Class accounts, but Comcast just recently (<2 months ago) closed off port 25 for all their email accounts. try using port 587
http://customer.comcast.com/help-and-support/internet/email-client-programs-with-xfinity-email/
The first place to look is in the mail server logs of the outgoing mail server that you are using to send this message. These should tell you whether or not the mail server is even receiving the message from your C# program for queuing, and if so - what's happening when it attempts to deliver the message to the remote MTA.
Well about 5 hours after I started testing, I got all my test emails at once including the embedded HTML and everything else. So it is working just as it should. I guess since the signature was slightly different they block them until they are deemed non-spam. It also appears that now when I send an email it goes through instantly.
So Comcast has some sort of time delay filter apparently for anybody else in the future with this problem.
I ended up adding mails to the (to list),
and put sending in foreach for every mail I send mail separately,
and it worked!
I have a little C# email app that runs on a server. When launched it sends one email and then goes away. Most of the time it works fine, but every so often it will give the below error:
System.Net.Mail.SmtpFailedRecipientException: Mailbox unavailable. The server response was: 5.7.1 Unable to relay for joe123#msn.com
at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, SmtpFailedRecipientException& exception)
at System.Net.Mail.SmtpClient.Send(MailMessage message)
at AppEmail.clsEmailMgr.SendEmail(MailMessage inMM, Int32 inTriesLimit, Int32 inSleepTime)
at AppEmail.clsEmailMgr.MainProcess()
I have looked at some other postings on this type of error, but they tend to focus on the server setup - which I think is correct - or else this app would never work... and most of the time it does.
One other note: This app can get called multiple times fairly rapidly, so there can be situations in which different instances of itself are trying to send emails at almost the same time. Could a SPAM filter be blocking some of the email sending attempts? Any other ideas would be appreciated.
This error occurs depending on the server setup... it does not prevent your code from working all the time... BUT it prohibits sending eMail with a sender/from with a domain not allowed and/or sending eMail to a domain not allowed... thus the mentioning of "relay" in the error...
Usually if you ask the server to send an eMail from a#b.com and the server is only setup for the domain c.com then this error comes up... otherwise it would be vulnerable to abuse by spammers (google for: spam open relay)... if your app needs to do such "relaying" for legit reasons then ask the mail server admin to configure the mail server that it allows relaying for the machine hosting your app...
Rapidly sending shouldn't be a problem except it could be perceived as an infected machine trying to send loads of spam... since you don't tell anything regarding the quantity per time unit this is pure speculation...
I faced similar intermittent issue (unable to relay) with one of my application. I verified the SMTP host log and the error recorded there was 'Auth login' failure. Finally, we tried passing the SMTP credential username in UPN (universal Principal Name) format to the SMTP client.
Example: Use username#abc.com instead of domain/username
This will give consistent result.
I am trying to send mail through my Google Apps email account. This is setup on my own domain and is all working fine through the web interface and through outlook.
However, i'm trying to send an email from a webpage using C#, I get no exceptions and everything appears to go smoothly, but the emails never seem to arrive:
MailMessage msg = new MailMessage("no-reply#xxxx.co.uk", "dan#xxxx.co.uk");
SmtpClient smtp = new SmtpClient("smtp.gmail.com", 587);
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.Credentials = new NetworkCredential("no-reply#xxxx.co.uk", "xxxxxxxxx");
smtp.EnableSsl = true;
msg.IsBodyHtml = true;
msg.Body = body;
smtp.Send(msg);
The body is a string which i've generated earlier in the code. As far as i'm aware, if there was a problem with actually connecting to the SMTP server at Gmail then I would get an exception thrown.
Any ideas what could cause this not to work? Only thing different I can see compared to other peoples examples is that I have set body as HTML and i'm sending from a Google Apps account rather than an #gmail.com account.
The google apps itself is all configured fully and working, i've set this up numerous times so I know it's not likely to be a problem there.
I also tried sending on port 25, as that's what you use when configuring Outlook to send from a Gmail account.
Same result for both, no exception thrown, but email never arrives. Both emails the sender and receiver are on my domain using Google Apps for Gmail.
EDIT:
Also I should mention that I have signed in using both accounts, and both have IMAP and POP enabled in their settings etc.
New findings
This is a strange one
If I send mail manually from:
no-reply#mydomain.com to dan#mydomain.com - Then it works
But if I send it through code this way...it doesn't work...
If I send the following through code it does work:
no-reply#mydomain.com to me#gmail.com or me#ntlworld.com - This works through code!
I would then be led to think that this means a problem with dan#mydomain.com receiving messages...But it receives any messages sent manually from any google, hotmail, or ntlworld email address i've tried.
So either Google Apps accounts can't receive email sent through code (unlikely) or something else is at play here
The server may silently discard your message if there is a problem with it.
- Despite any spec saying otherwise.
The message might be lost in the ether despite being "delivered".
The SMTP server may be applying severe filtering and might additionally require that your sender and destination email addresses match up 'correctly'
I suggest trying with a different SMTP host just to check. :)
When you setup Google Apps, even if the MX records are all working correctly for sending mail manually to/from other accounts, there can still be problems.
The answer is to wait 12-24 hours after setting up your MX Records, even if everything else is working fine.
If you receive no exception, then to me this is the only answer at the moment.
All is working correctly now. Even though all MX records were correct on my DNS and email appeared to be working, there were still changes going on in the background
I use C# to send email using System.Net.Mail.
But How can I know whether the email has been sent successfully or fail?
Not a direct answer of course, but here is a great article from Coding Horror about sending emails through code, which addresses your question.
The simple answer is that if it's a detectable failure then SmtpClient.Send will throw an SmtpFailedRecipientsException (it will throw an SmtpException if there is a connection problem).
The long answer is that, for many reasons, you won't necessarily get an exception. This can be because your SMTP server is buffering the sends (or if you have it set to local iis or local directory), or simply because the SMTP server does not support returning those error codes.
Most advertising mailing systems track bouncebacks by setting a valid "from address" and monitoring the inbox for that account. Even that, however, is not foolproof (out of office messages, for example).
I would stick to catching exceptions and leaving the others. If you're not sure if emails are valid, maybe you should send users a code to have them validate their email address.
Considering Emails are fire-and-forget, this can be quite hard. Unless you get an exception, denoting a client-server communication issue due to wrong credentials etc, you have no means of knowing if a mail was sucessfully send (meaning: arrived at the addressee).
I've personally never come across an answer to this as there's not really a way you can grantee mail leaving your location is'nt going to get thrown away as soon as it leaves you. You could maybe try and check the sending mailbox for an NDR (none delivery report) but your not always granted to get one
If you mean sent successfully then as other posters say, if it cannot be sent then you will get an exception. If you actually mean recieved succesfully then that is an entirely different matter. SMTP simply does not have a mechanism to find out if the message has been recieved by the recipient, sometimes you will get an ndr if a server can't deliver other times you won't. You could try and do what spammers do and that is to put some kind of image link in your html email body with a unique identifier in the query string. That would allow you to link someone hitting the image url with the email. However that would only tell you the email had been read if the url was hit, it would not tell you that the email hadn't been recieved becuase the recipient might simply not have allowed images to be displayed in their email client.