Mailkit Timeout Exception

Viewed 1088

I am working on a small application where I have to send emails, using MailKit, when triggered. My development environment is Windows and Production environment is Ubuntu 20.04 LTS.

In my dev environment, the emails are being sent successfully but when the same code is deployed on my linux machine, it shows

TimeoutException: The operation has timed out.

Following is the Exception log;

MailKit.Net.SocketUtils.ConnectAsync(string host, int port, IPEndPoint localEndPoint, int timeout, bool doAsync, CancellationToken cancellationToken)
MailKit.MailService.ConnectSocket(string host, int port, bool doAsync, CancellationToken cancellationToken)
MailKit.Net.Smtp.SmtpClient.ConnectAsync(string host, int port, SecureSocketOptions options, bool doAsync, CancellationToken cancellationToken)
MailKit.Net.Smtp.SmtpClient.Connect(string host, int port, SecureSocketOptions options, CancellationToken cancellationToken)
MailKit.MailService.Connect(string host, int port, bool useSsl, CancellationToken cancellationToken)
XYZProject.Controllers.HomeController.TriggerException(string fileType) in D:\DotNet\DotNetCore\XYZProject\XYZProject\Controllers\HomeController.cs
XYZProject.Controllers.HomeController.Index(UploadFormViewModel model) in D:\DotNet\DotNetCore\XYZProject\XYZProject\Controllers\HomeController.cs
lambda_method35(Closure , object , object[] )
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

One point to note here why I am getting my windows path in linux machine.

Here is the function I am calling for sending email;

private void TriggerException(string fileType)
{
    int port = Convert.ToInt32(_configuration["AlarmTrigger:Emails:Credentials:SmtpPort"]);
    string host = _configuration["AlarmTrigger:Emails:Credentials:SmtpServer"];
    string username = _configuration["AlarmTrigger:Emails:Credentials:User"];
    string password = _configuration["AlarmTrigger:Emails:Credentials:Password"];

    MailboxAddress mailFrom = new MailboxAddress(_configuration["AlarmTrigger:Emails:From:Name"],
        _configuration["AlarmTrigger:Emails:From:Email"]);

    MailboxAddress mailTo = new MailboxAddress(_configuration["AlarmTrigger:Emails:To:Name"], 
        _configuration["AlarmTrigger:Emails:To:Email"]);

    string mailTitle = "Failure Notification";
    string mailMessage = "Dear Team, \n\r" + fileType + " file upload failed.";

    var message = new MimeMessage();
    message.From.Add(mailFrom);
    message.ReplyTo.Add(mailFrom);
    message.To.Add(mailTo);
    message.Subject = mailTitle;
    message.Body = new TextPart("plain") { Text = mailMessage };

    using (var client = new SmtpClient())
    {
        //client.LocalDomain = "localhost";
        client.Connect(host, port, true);
        client.Authenticate(username, password);

        client.Send(message);
        client.Disconnect(true);
    }
}
2 Answers

A socket will get a timeout exception during the Connect call if/when the socket is unable to make a connection to the remote host on the specified port within the configured time span (which, by default, is 2 minutes).

You have a few avenues to explore in order to solve this issue:

  1. You can try increasing the timeout by setting the SmtpClient.Timeout value.
  2. Verify that you are using the correct host name and port.
  3. Verify that your production environment is not blocking outgoing connections to the mail server on the port that your program is trying to use via a firewall or virus scanner.
  4. Verify that the ISP or whatever is not blocking your production server's outgoing connections via their firewall.
  5. Verify that the production environment's routing tables are correct and that there is a valid network route to the SMTP server.

You can use this one.

                    MailMessage mail = new MailMessage();
                    SmtpClient SmtpServer = new SmtpClient("smtp.live.com");
                    mail.From = new MailAddress("username@hotmail.com");
                    mail.To.Add("Mail Adress");
                    mail.Subject = "Your Subject";
                    mail.Body = "This is for testing SMTP mail from GMAIL";
                    SmtpServer.Port = 587;
                    SmtpServer.Credentials = new System.Net.NetworkCredential("username@ghotmail.com", "Your PAssword");
                    SmtpServer.EnableSsl = true;
                    SmtpServer.Send(mail);
Related