Net::SMTP Unexpected EOF error

I've searched the net, and couldn't find anything about a problem I'm having with Net::SMTP.
Could you suggest something or direct me somewhere about this problem ?  Ultimately I'm looking to get it resolved.
I get the error at various parts of the SMTP conversation, either after $smtp->to or $stmp->dataend(), etc.
The logs are like this:
Net::SMTP=GLOB(0x80664e4)>>> .
Net::SMTP: Unexpected EOF on command channel at line 163
From what it looks like, remote server drops the connection unexpectedly, yet I may be wrong.  I want to be able to know when this happens, so I can deal with it in my script.

I tried if (undef($stmp)) die "EOF error again";
However, this doesn't do it.  Even though $smtp should NOT be defined anymore, it seems to still 'be there", and program skips right past it.  Hence the script continues on (much faster though, since it doesn't really send anymore), and tells me that ALL emails were sent, when in fact the script stopped sending emails after the EOF error.  The only way to find out where it really stopped sending is to go to the log, where I found that EOF error.  What I want to do is to automatically stop any and all processing when that error happens.  In other words, do something like throw () catch () exception handling and deal with it from there.  Or anything else that will do the job.

Is there a way to do that ?  

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

I thnk you may be able to test for it by looking at the return value from each call. They should return false or undef if they fail.
To put it in a try-catch style, wrap it in an eval and call each method as
$smtp->method() or die "Something descriptive";

Part of the descriptive message might be the returned status message: $smtp->code() or $smtp->message(). See the Net::Cmd doc for more details.

The eval will also take care of the instances where your $smtp object is undefined.
could you please post relevant parts of your code (including the use and new statements)
dennismvAuthor Commented:
thanks. .  I'm still testing it

code so far..
use Net::SMTP;  
use strict;

$smtp=Net::SMTP->new($server, Timeout => 15, Debug => 1);

$smtp->to( $mailto );
$smtp->data();       # Start the mail  

# headers  
$smtp->datasend("From:  $mailfrom\n");  
$smtp->datasend("To:  $mailto\n");
$smtp->datasend("Subject: $subject\n");  

# body.  
$smtp->dataend(); # Send the termination string  

What I did, I put "or last;" at the end of each $smtp command instead of "or die 'desc.message';", because I have the above in a while loop
I don't know if it works yet, haven't had any errors.  I'll test it some more to make sure it does work.

Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.


I would advise you to use "\r\n" instead of "\n" in $smtp->datasend() method.
Let me know if this solves your problem.

Also are you trying to send some attachments?
Let me know.


dennismvAuthor Commented:
no, no attachments, thanks for \r\n, I'll put it in.
but why ?  I thought \r\n is for more Windows, while \n is for unix encoding.  what's the difference ?


what is $server set too?
and you're missing a final
don't worry about the newline differences. Officially the SMTP protocol (and many other protocols) specify \r\n as newline character, but Net::SMTP takes care of that for you. See the documentation of Net::Cmd:
"datasend ( DATA )
    Send data to the remote server, converting LF to CRLF."

What I tried to explain with wrapping the smtp conversation in an eval block is the following:

eval {
  $smtp->mail($from) or
    die "Error sending to $from: " . $smtp->code() . ' '. $smtp->message();

  $smtp->to($to) or
    die "Error sending to $to: " . $smtp->code() . ' '. $smtp->message();

  $smtp->data($data) or
    die "Error sending data $data: " . $smtp->code() . ' '. $smtp->message();

if($@) {
  print STDERR "Error sending mail: $@";

The eval{} is like a try{} block in Java. The 'die' statements correspond to throw. If a die gets triggered, it takes you out of the eval{} block, setting $@ to contain the message. So the if($@) is like the catch part.
This way you can continue your code and know when and why it failed.

dennismvAuthor Commented:
this is just an update.  eval helped to kinda track down some problem areas, but I still get the error.  However, I am not yet stuck, as I still have things to try before I 'give up'.

Just so you know how it's going:
the log usually goes like this:
Net::SMTP=GLOB(0x82616e0)>>> MAIL FROM:<>
Net::SMTP=GLOB(0x82616e0)<<< 250 sender <> ok
Net::SMTP=GLOB(0x82616e0)>>> RCPT TO:<>
Net::SMTP: Unexpected EOF on command channel at line 211
Sending test message to -->
Exiting eval via next at line 254, <DATA> line 11.
Sending test message to -->
Exiting eval via next at line 254, <DATA> line 12.

NOTE:  after the EOF error server stops replying completely.  That's what I called "the script going awry" -- I can't regain the control of it.
I test the connection every email by this line:
if (undef($smtp)) die "smtp undef";  
but the server keeps going, without giving any response, so
apparently $smtp is still defined, yet it's practically dead..

Unexpected EOF happens on any of the lines where I have
$smtp->command();  #where "command" may be any of the to,from,datasend,etc.

And what's interesting is, i.e. in this case I have the command from line 254 as from the error above:
if ($smtp->to($to)==0) {print "bad recipient or unexpected EOF";};

self explanatory, but I'll reiterate:
$smtp->to() gives 0 if it's bad rcpt, or the EOF error.
it still gives 0 when the server doesn't reply anymore.
So I can't differentiate the two.  And depending on which one it is, I want different processing.  

So the (new) definition of the problem is .. how do I know when server stops replying.

I tried $smtp->response(), but it always times out, no matter what.
So, I am still trying things .. like maybe I'll try $smtp->code (); and see what it does.  It may differentiate between bad rcpt and EOF.  Then, if I know it's EOF I can halt the script without it going awry, and that's what I've been looking for.


might be a reason for EOF, depending on the server ...
dennismvAuthor Commented:
I have $smtp-quit(); at the end :)  I forgot to mention it last time.
However, the error happens in the loop, before $smtp->quit();


If I understand the documentation for Net::Cmd correctly, $smtp->response() is a method for obtaining a response from the server. You should not call this yourself, Net::SMTP uses this internally. To be specific, it is being called after every $cmd->command() call (which sends a command to the server).

Please test the return values of $smtp->ok() or $smtp->code() and $smtp->message(), because they should contain the last response from the server.

If I'm reading Net::Cmd correctly, it will set code to 599 and message to 'Connection closed'.

BTW, I found your error message in Net::Cmd's getline() routine (on line 273), and it closes the connection right after it reports that. So you will know the connection is closed in this instance.

So, check $smtp->code(). If it equals 599, you know the connection has been closed, and you should reconnect (by setting $smtp = new Net::SMTP($server).

Hope this clarifies stuff a bit.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dennismvAuthor Commented:
Thanks, Kandura !

eval and $smtp->code() helped.  $smtp->message() may also help if I'll need it later on.
I've regained control of the script ! :)

and thanks to everybody for hints and suggestions,
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.