SMTP Error Codes and determining if email is still delivered - c#

I am using System.Net.Mail to to send mail. I do not know the type/version of the SMTP relay that it will connect to.
Some errors will result in no email being sent (e.g. no addresses or invalid from address) whilst others errors will still result in an email being sent.
E.g. Send To : bob#somewhere.com CC: fred#somewhere.com and DoesNotExist#somewhere.com may result in an error of
The server response was: 550 #5.1.0 Address rejected DoesNotExist#somewhere.com.
But the email still appears to be delivered to Bob and Fred.
Is there any reference to which error codes will still result in an email being delivered or any programmatic way of determining this?

This is the way that SMTP operates, as described in the RFC.
Failure to deliver to one recipient does not affect delivery to other recipients.
Generically, codes starting with 4 and 5 are failures, codes starting with 2 are success codes - see RFC821 section "4.2.2. NUMERIC ORDER LIST OF REPLY CODES".
"Email being delivered" is hard to define. Email being accepted for delivery by the SMTP server is defined by the SMTP protocol (and the server will signal acceptance to deliver a message) but this server might just relay the message to another server, or operate in a smart host configuration where it just accepts messages and passes them on to the smart host - delivery is another thing and it's usually associated with local delivery (LMTP).
Some mail clients work around this problem of not being able to tell if a message has been delivered by implementing the dreaded read receipts - but this implementation is entirely on the client side and AFAIK it has nothing to to with SMTP.

RFC 821 is the one that describes SMTP and includes information about different types of errors, but not sure if it contains the details you're looking for. And either way, even if you can find out that the mail server accepted the email for some users, that is not the same as saying that it was delivered to them.
As far as I know, there is no way of telling if an email has been delivered except if the recipients mail client will tell you in some way.

Non-delivery reports (NDRs) are system messages that report the delivery status of a message to the sender. The messages are a subclass of a general message information structure that is referred to as delivery status notifications. Delivery status notifications describe three different types of situations:
* Success (2.X.X numeric codes)
* Persistent transient failure (4.X.X numeric codes)
* Permanent failures (5.X.X numeric codes)
To learn more about delivery status notifications, see Request for Comment (RFC) 1891 and RFC 1893.
Qouted from Microsoft Support http://support.microsoft.com/kb/284204

Related

send email to many recipients in C# check which one fail

References to this link, I understand how to send email to many recipients my question is if one of them fail this mean Send(Msg) will throw error for all ? or just for specific recipient appreciate any help thanks
Assuming you are using System.Net.Mail.SmtpClient.Send(MailMessage), the documentation shows that it can throw a "SmtpFailedRecipientsException" exception when the message could not be delivered to one or more of the recipients in MailMessage.To, MailMessage.CC, or MailMessage.Bcc.
The SmtpFailedRecipientsException exception has an InnerExceptions property.
Gets one or more SmtpFailedRecipientExceptions that indicate the e-mail recipients with SMTP delivery errors.
https://msdn.microsoft.com/en-us/library/swas0fwc(v=vs.110).aspx
Note: Depending on the issue, the SMTP server may accept the message and fail to deliver it to the recipient further along in the process.

Exchange 2013 Transport Agent Sending Separate Email for Internal Vs External Recipients

We are currently going through a proof of concept creating a Transport Agent that is derived from the Microsoft.Exchange.Data.Transport.Routing.RoutingAgent. We use the OnResolvedMessage event to reroute emails to our external Email server (non Exchange server). This all works fine, and we can reroute the emails to the external server. However, it appears that if an email contains both an internal and external recipient the email will be split into two separate emails and result in two emails going to the external email server. While the two emails contain the same content, just different RCPT TO headers, this will cause the external email server to process the same email twice which is less than desirable for our project.
This is my first time creating a transport agent, and I am trying to determine if there is some setting for exchange server that needs to be changed in order to stop emails that meet this criteria from being split into multiple emails?
The main goal of our transport agent will be to allow emails going to internal recipients to be processed by the external email server, as they currently will be placed into the internal user's mailbox unprocessed. It might have to do with our send/receive connectors, any guidance on any gotchas around those would be much appreciated. If a routing agent is not the correct solution for this problem, we are open to other possibilities.
Snippet of our event handler:
private void OnOnResolvedMessage(ResolvedMessageEventSource source, QueuedMessageEventArgs queuedMessageEventArgs)
{
var mailItem = queuedMessageEventArgs.MailItem;
var origSubject = mailItem.Message.Subject;
mailItem.Message.Subject = "RouteAgent: " + origSubject;
foreach (var recipient in mailItem.Recipients)
{
var newRouteDomain = new RoutingDomain("externalSendConnectorAddressSpace.com");
var dest = new RoutingOverride(newRouteDomain, DeliveryQueueDomain.UseOverrideDomain);
source.SetRoutingOverride(recipient, dest);
}
}
By the time OnResolved Message gets called in the Transport Pipeline the recipients will have been resolved and Bifurcation will have happened on the Message the rules for which are mostly explained in https://technet.microsoft.com/en-us/library/bb430743(v=exchg.150).aspx . EdgeTransport.exe.config is the place where the configuration of the Transport pipeline can be done but I don't believe there is any configuration option for what your trying to do.
If you catch the Message in OnSubmission event this will allow you to get the Message before any categorization has occurred. At that point you can more or less do what you want to the Message. However there are other things that occur as part of the Categorization process such as content conversion https://technet.microsoft.com/en-us/library/bb232174(v=exchg.150).aspx .
However, it appears that if an email contains both an internal and external recipient the email will be split into two separate emails and result in two emails going to the external email server. While the two emails contain the same content, just different RCPT TO headers, this will cause the external email server to process the same email twice which is less than desirable for our project.
This shouldn't really be a big deal for the external service as this should be something that would be expected in any process that was processing emails eg its easy for the external service correlate using the Internet MessageId etc. IMO your trying to solve the problem at the wrong end.
Cheers
Glen

How to handle bounce email messages when you send emails on behalf of customer

I need advice on processing/tracking bounce emails.
We have a scenario, where we need to send emails to recipient on behalf of our customers.
lets say we need to send email to user#recipient.com with from as emailer#cusotmer.com but when this email fails we need to receive the bounce/failure notification on mybouncetracker#mydomain.com
I tried using the reply-to/return-path but both getting replaced with emailer#cusotmer.com.
We were not able to process bounce message as we dont own the inbox for emailer#cusotmer.com.
Please help!!..
We created smtp client on C#.net
Please be advised that we can't rely on the reply-to headers or inserting a custom ID to our original message's headers since the bounced messages returned by the mail servers vary from server to server. Many of them just bounced with a plain-text saying that the delivery is failed without including the original message.
My advise is to use Regex with compiled options (for performance) to scan the messages.
After you have read the message content, you can use the following code to classify a message as a soft bounce that states that the message sending was failed:
string pattern = "failed after \S+ sent[\s\n]the[\s\n]message";
Regex regexPattern = new Regex(pattern, RegexOptions.Compiled);
if (regexPattern.Match(myMessage.BodyHtml))
{
Console.WriteLine("This is a soft bounce");
}
You can add more patterns to classify more messages.

Throwing Exception while sending Email to multiple recipients using smtp client

I have an application which uses SmtpClient to send an email. I am trying to send an email to multiple recipients. I have two recipients in my to list e.g "aman#gmail.com,abc#xyz.com". and I am trying to send the email to this list but my application is throwing the exception as below:
Client does not have permission to submit mail to this server. The server response was: 4.7.1 (abc#xyz.com): Relay access denied.
because of this aman#gmail.com is also not able to receive the email.
I need to implement the functionality that even there is an invalid address like abc#xyz.com in the ToList, an email should be sent successfully to aman#gmail.com.
Can anybody please help me in this?
Does this error message come from your own email server, or from that of xyz.com? I'm guessing it's your own server, and that you either need to aunthenticate before sending, or use your own email address for sending (but the latter is kind of a long shot -- "we do not relay" means a server which is neither the sender's or the recipient's refuses to act as a middleman). It is also possible that the mail exchanger for xyz.com is misconfigured (either the MX record in DNS points to the wrong server, or the admin failed to configure it to accept this responsibility - technically basically the same thing) or that your client somehow ends up connecting to the wrong place.
(Not a proper answer but this got too long to fit in a comment.)

POP3 Transmission Process

I was wondering if anyone could help me out (not with code, although that would be appreciated), with the logic behind checking and retrieving messages from a POP3 mail server.
I.e.
Establish connection
Validate credentials
Enumerate message list
Check each message to see if it's "new"
Download "new" message(s).
Would this be the correct way about doing this?
Thank you
The best way of looking at something like this is to have a look what something else does. Run Wireshark or some other packet capture software, and use an e-mail client to check. Anyway, the basics of a POP3 session are as follows:
USER username
PASS password
LIST <-- Shows the size of each waiting message
UIDL <-- Shows a unique ID for each waiting message
RETR 1 <-- Retrieves message with index 1
DELE 1 <-- Deletes the message you just retrieved
QUIT
The first char of all of the responses except RETR will be a + (success) or a - (failure).
If you are deleting messages off the server after retrieving them, you don't need to bother with UIDL. If you are leaving them, you can use UIDL to get a unique ID for each message which you store locally to show you have retrieved that message before.
For more details, see the RFC. Wikipedia also lists a more in depth example, showing the server response.
These should be useful:
POP3 Email Client (.NET 2.0)
POP3 Client as a C# Class
Retrieve Mail From a POP3 Server Using C#
POP3 Sequence Diagram
POP3 Reference

Categories