martybugs.net Linux Info
 navigation
. MartyBugs home
. linux info home
 
 software info
. installing RRDTool
 
 system health
. HDD Temp Monitoring
. Imaging a PC
 
 network traffic
. Traffic Monitoring with RRDTool
. Bandwidth Monitoring with ipac-ng
. WAIX IP Accounting
 
 wireless info
. Wireless Info
. Link Monitoring with RRDTool
 
 router config
. Linux Wireless Router
. Smoothwall Info
. Multiple AS with Quagga
 
 site search
Custom Search
 
Resolving a Bad Hostname Error in Net::SMTP Perl Module

This page describes how I debugged some issues being experienced with the Net::SMTP perl module, and how the issue was eventually resolved.

Background Information

Web Environment

I have a photography blog hosted on a shared linux webserver in a data centre, and one of the features it supports is email notification whenever someone leaves a comment. The blog is coded in Perl, and uses the Net::SMTP perl module to send the email notifications.

When calling the Net::SMTP module, I specify the hostname of a mailserver that it uses to send the email. It's important to note that the mailserver is in a different data centre than the webserver (ie, the mailserver software is not running on the same box as the webserver software).

Symptoms of the Issue

In the past few weeks, I had noticed that occasionally I wouldn't receive an email when someone left a comment.

A friendly visitor emailed me recently, to let me know that he tried to leave a comment, he saw a "500 Internal Server Error" page after submitting the comment. His comment had been saved, but the email notification had failed, and the code on the webserver that was attempting to send the email notification had failed, causing the 500 error.

A check of the apache error log on the webserver showed:

[Sun Sep 21 08:53:39 2008] [error] [client a.b.c.d] Can't call method "auth" on an 
undefined value at /path/blog/plugins/feedback line 897, <GEN> line 200.

This appeared to indicate the error was being encountered during authentication to the mailserver by the Net::SMTP module.

Initial Investigation

Checking the Code

The first action was to check the code in my blog software that was attempting to send the notification email. Here's a snippet of code:

    # define parameters for sending email
    my $smtp_server = "mail.server.hostname";
    my $address = "me@my.domain.name";
    my $pwd = "mail_password";
    
    # load modules
    require Net::SMTP;
    Net::SMTP->import;

    # create instance of module, specifying mailserver
    my $smtp = Net::SMTP->new($smtp_server);
    
    # login to mailserver if password is specified
    if ($pwd)
*   { $smtp->auth ($address, $pwd); }

    $smtp->mail($address) or warn "net::smtp failed to set mail address\n";

    ....

I've highlighted the line referenced in the error mentioned earlier with a red *, and this is the line attempting to call the auth method of the Net::SMTP module.
However, the error specified that the auth method was being called on an undefined value, which indicated the Net::SMTP module was either failing to load, or the code was failing to create a new instance of it.

Add Error Handling

I added some error handling around the code that attempted to load the Net::SMTP module and create a new instance of it, so I could determine exactly where it was failing.

    # load modules
    require Net::SMTP or warn "feedback: net::smtp failed to do require\n";
    Net::SMTP->import;

    # create instance of module, specifying mailserver
    my $smtp = Net::SMTP->new($smtp_server) 
     or warn "feedback: net::smtp failed to create object ($!; $@)\n";

(Note that for some reason, the Net::SMTP->import; line always returns false, so I removed the error handling initially added to it, as it wasn't useful.)

The error handling ensures any issues with the module loading, or creation of a new instance, would be logged, along with the error details (as contained in $! and $@).

Identifying Where The Problem Is Occurring

Reproduce The Problem

While attempting to reproduce the problem (by repeatedly submitting comments on a blog post), I noticed that the error occurred approximately once in ten attempts, with the other nine attempts to send an email succeeding.

Error Details

When the problem reoccurred, the apache error log showed:

[Wed Sep 24 16:32:39 2008] [error] [client a.b.c.d] feedback: net::smtp failed to create 
  object (Invalid argument; Net::SMTP: Bad hostname 'mail.server.hostname')

Now I was starting to get more useful info, as this told me the creation of a new Net::SMTP object was failing, with an Invalid argument error, and an error message saying Net::SMTP: Bad hostname 'mail.server.hostname'.

This confirmed that the error was occurring when attempting to execute the following line:

    my $smtp = Net::SMTP->new($smtp_server);

Further Investigation

Googling the "Bad hostname" error indicated the SMTP server could return this error if there was a problem with the hostname of the mail client (ie, the webserver where this code was running). To determine if this was the problem, I changed the code to explicitly specify the client domain:

    my $smtp = Net::SMTP->new($smtp_server, Hello => 'mail.server.hostname')
     or warn "feedback: net::smtp failed to create object ($!; $@)\n";

However, this didn't resolve the problem, and it could still be reproduced approximately once in ten attempts, so the Hello parameter was removed.

Brainstorming

Other Causes?

I was wondering if the issue could possibly be occurring if the mailserver hostname was failing to be resolved by DNS.

A quick check on the webserver indicated it was using a single DNS server (as specified in /etc/resolv.conf). This DNS server was in the same data centre as the webserver, so there shouldn't be any latency issues between the webserver and the DNS server.

Testing DNS

Repeatedly attempting a DNS lookup, using the same DNS server that the webserver was using, of the mailserver hostname being used by Net:SMTP provided some interesting results, with the DNS lookup occasionally failing with a timeout:

    ;; connection timed out; no servers could be reached

Note that these tests were performed on the webserver itself, to simulate the DNS query as closely as possible that would be performed when the Net::SMTP module is attempting to resolve the mailserver hostname. The DNS queries were executed using the following syntax:

  nslookup mail.server.hostname a.b.c.d

where mail.server.hostname is the hostname of the mailserver that is to be used for sending email, and a.b.c.d is the IP address of the DNS server that's being used by the webserver.

Resolution

Summary of Issue

The DNS testing confirms that the Net::SMTP module is occasionally failing to send email because the webserver was failing to resolve the mailserver hostname, due to requests to the DNS server timing out.

The Fix

My webhost is only a small company, and the server admins are easy to contact. I explained the issue to them, and asked them to add some additional DNS servers into the /etc/resolv.conf on the webserver where this particular site is hosted. With multiple DNS servers specified, if a query to one server times out, it'll try the next DNS server, and will repeat until a maximum number of retries have been made.

Conclusion

Since the DNS configuration change on the webserver was made, I have not been able to reproduce the problem.
It certainly demonstrates that when debugging a software issue, don't rule out the basics such as DNS!



last updated 2 Dec 2012
 
.