C# – Getting a ASP Error: Mailbox unavailable. The server response was: Access denied – Invalid HELO name (See RFC2821 4.1.1.1)

asp.netcsmtp

I am getting an error and I know my credentials are correct. Any ideas? This is on a Windows Server but I am wanting to use Hostgator SMTP settings for my email. This is what happens when I submit a simple contact form.

ERROR:
Mailbox unavailable. The server response was: Access denied – Invalid HELO name (See RFC2821 4.1.1.1)

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Net.Mail.SmtpException: Mailbox unavailable. The server response was: Access denied – Invalid HELO name (See RFC2821 4.1.1.1)

Source Error Line 61:

Line 59:            
Line 60:             SmtpClient smtp = new SmtpClient(SMTPServer, SMTPPort);
Line 61:             smtp.Credentials = new NetworkCredential(SMTPUserId, SMTPPassword);
Line 62:             smtp.Send(mail);
Line 63:         }

Source File: \Websites\Client\Reports\ContactUs.aspx.cs Line: 61

=========================================================================

My Source Code:

  protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
    {
        string name = txtFirstName.Text + " " + txtLastName.Text;
        string clientID = Session["CustomerID"].ToString();
        string message = txtMessage.Text;
        string email = txtEmail.Text;
        string company = txtCompany.Text;
        string phone = txtPhone.Text;

        SMTPMailHelper.SendMail(email, "myemail@domain.com", "Contact from Client: " + clientID + ": " + name + " " + company, message);
    }

I LEFT OUT SOME SCRIPT THAT DID'T MATTER SUCH AS CONDITIONAL STATEMENTS.
AND THIS IS THE REST OF IT:

 public class SMTPMailHelper
{
    const string SMTPServer = "mail.mydomain.com";
    const string SMTPUserId = "myemail@mydomain.com";
    const string SMTPPassword = "MyPasswordHidden";
    const int SMTPPort = 25;

    public static void SendMail(string sendFrom, string sendTo, string subject, string body)
    {
        MailAddress fromAddress = new MailAddress(sendFrom);
        MailAddress toAddress = new MailAddress(sendTo);
        MailMessage mail = new MailMessage();


        mail.From = fromAddress;
        mail.To.Add(toAddress);
        mail.Subject = subject;

        if (body.ToLower().Contains("<html>"))
        {
            mail.IsBodyHtml = true;
        }

        mail.Body = body;


        SmtpClient smtp = new SmtpClient(SMTPServer, SMTPPort);
        smtp.Credentials = new NetworkCredential(SMTPUserId, SMTPPassword);
        smtp.Send(mail);
    }
}

Best Answer

The problem you are having is that the SmtpClient is issuing a HELO or EHLO command with a hostname/domain string that your server is SMTP rejecting.

I obviously cannot know the inner logic of Microsoft's SmtpClient implementation, but I suspect that you are probably behind a NAT which means that the SmtpClient cannot resolve the world-viewable fully qualified domain name of your machine. It can only resolve the FQDN of your machine on your "internal network" (and realistically, it probably can't even resolve it to an actual FQDN, it probably has to settle for the internal network IP address).

So... SmtpClient is probably sending something like EHLO [192.168.1.100] (or whatever your local IP is) and the server is rejecting it because that is not the IP address that it is receiving packets from.

What you'll need to do is find your external IP address by visiting a site like http://www.whatismyip.com/ or using the hostname detected by a site like http://www.displaymyhostname.com/.

To illustrate what I am talking about, here's a little demo program:

using System;
using System.Net;
using System.Linq;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Net.NetworkInformation;

namespace LocalHostName
{
    class Program
    {
        static void Main (string[] args)
        {
            var ipAddresses = Dns.GetHostAddresses ("www.google.com");
            Socket socket;

            for (int i = 0; i < ipAddresses.Length; i++) {
                socket = new Socket (ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                try {
                    socket.Connect (ipAddresses[i], 80);
                    Console.WriteLine ("LocalEndPoint: {0}", socket.LocalEndPoint);
                    break;
                } catch {
                    socket.Dispose ();
                    socket = null;

                    if (i + 1 == ipAddresses.Length)
                        throw;
                }
            }

            Console.ReadLine ();
        }
    }
}

Whatever IP address it prints out is likely to be the one that SmtpClient is using in its HELO/EHLO command.

The bad news is that there's no way to work around this problem with System.Net.Mail.SmtpClient.

The good news is that I saved 15% on my car insurance... er, I mean, I've written my own email libraries called MimeKit and MailKit that can work around this problem.

Some more good news is that you can easily cast your System.Net.Mail.MailMessage object into a MimeKit.MimeMessage object (although, obviously, it would be better to switch completely over to MimeKit and MailKit).

var mimeMessage = (MimeMessage) mailMessage;

Here's what your re-written SMTPMailHelper class would look like using MimeKit and MailKit:

using System;
using MimeKit;
using MailKit.Net.Smtp;

public class SMTPMailHelper
{
    const string SMTPServer = "mail.mydomain.com";
    const string SMTPUserId = "myemail@mydomain.com";
    const string SMTPPassword = "MyPasswordHidden";
    const int SMTPPort = 25;

    public static void SendMail(string sendFrom, string sendTo, string subject, string body)
    {
        MimeMessage message = new MimeMessage ();
        TextPart text;

        message.From.Add (new MailboxAddress ("", sendFrom));
        message.To.Add (new MailboxAdress ("", sendTo));
        message.Subject = subject;

        if (body.ToLower ().Contains ("<html>"))
            text = new TextPart ("html") { Text = text };
        else
            text = new TextPart ("plain") { Text = text };

        message.Body = text;

        using (var smtp = new SmtpClient ()) {
            // use the IP address gotten from http://www.whatismyip.com/
            // or the hostname gotten from http://www.displaymyhostname.com/
            smtp.LocalDomain = "c-24-71-150-91.hsd1.ga.comcast.net";

            smtp.Connect (SMTPServer, SMTPPort, false);
            smtp.Authenticate (SMTPUserId, SMTPPassword);
            smtp.Send (message);
            smtp.Disconnect (true);
        }
    }
}

The important bit is the string that you set the LocalDomain property of the SmtpClient to.

Related Topic