How to check if an email address exists without sending an email?

Posted by php-manual on Jan 16, 2009 in Web |

We have all been doing email address validation for a very long time to make sure that the email is correctly formatted. This is to avoid users entering wrongly formatted email address but still they can accidentally give us a wrong email address.

Example of a correctly formatted email address but still wrong:

mailbox.does.not.exist@reddit.com [VALID email fromat but still not correct]

Above case specifically happens when you take important customer email on phone and you type in the wrong email. So is there a QUICK solution to really check the email without sending a test message to the user? Yes.

The solution

A quick & simple check below can be implemented in most programming language including PHP, Python etc. It relies on using the same SMTP which is used to send emails.

To check if user entered email mailbox.does.not.exist@reddit.com really exists go through the following in command prompt.

First - Find mail exchanger of reddit.com

COMMAND:
nslookup - q=mx reddit.com
RESPONSE:
reddit.com      MX preference = 10, mail exchanger = mail.reddit.com
mail.reddit.com internet address = 208.96.53.70

Second - Connect to mail server mail.reddit.com

COMMAND:
telnet mail.reddit.com 25
RESPONSE:
220 mail.reddit.com ESMTP Postfix NO UCE NO UEMA  C=US L=CA Unsolicated electronic mail advertisements strictly prohibited, subject to fine under CA law CBPC 17538.45.  This electronic mail service provider’s equipment is located in the State of California.  See http://www.reddit.com/static/inbound-email-policy.html for more information.

COMMAND:
helo hi
RESPONSE:
250 mail.reddit.com

COMMAND:
mail from: <youremail@gmail.com>
RESPONSE:
250 2.1.0 Ok

COMMAND:
rcpt to: <mailbox.does.not.exist@reddit.com>
RESPONSE:
550 5.1.1 <mailbox.does.not.exist@reddit.com>: Recipient address rejected: User unknown in local recipient table

COMMAND:
quit
RESPONSE:
221 2.0.0 Bye

NOTES:

1) the 550 response indicates that the email address is not valid and you have caught a valid but wrong email address. This code can be on the server and called on AJAX when user tabs out of the email field.  The entire check will take less than 2 seconds to run and you can make sure that the email is correct.
2) If email was present the server will respond with a 250 instead of 550
3) There are certain servers with a CATCH ALL email and this means all email address are accepted as valid on their servers (RARE but some servers do have this setting).
4) Please do not use this method to continuously to check for availablity of gmail / yahoo / msn accounts etc as this may cause your IP to be added to a blacklist.
5) This is to supplement the standard email address javascript validation.

Telnet screenshot in windows - Check email using SMTP commands

UPDATE: PHP code added on 26th January 08

1) SMTP check code in PHP - DOWNLOAD

2) Usage example - DOWNLOAD

Tags: , , ,

55 Comments

Aleron
Jan 16, 2009 at 3:11 pm

A quick & simple check below can be implemented in most programming language including PHP, Python etc.

How?


 
Capt. Sparrow
Jan 16, 2009 at 3:13 pm

I had to use angle brackets <> with gmail. You will have to slightly change your instructions:
mail from: randomnonexist@gmail.com (with angle brackets)

Google came back with a long story saying that email address does not exist. Brilliant :)


 
Erhan Hosca
Jan 16, 2009 at 3:23 pm

what if the MX record resolves to an IP of a server thats configured to be a mail relay ?


 
php-manual
Jan 16, 2009 at 3:26 pm

A simple fsockopen command in PHP and you can open connection to any SMTP server with port 25.


$smtp_server = fsockopen("mail.reddit.com", 25, $errno, $errstr, 30);
fwrite($smtp_server, "HELO hi\r\n");
fwrite($smtp_server, "MAIL FROM: \r\n”);
fwrite($smtp_server, “RCPT TO: \r\n”);


 
Stephen Deken
Jan 16, 2009 at 3:31 pm

You could also use VRFY to confirm that the mailbox exists, but it might be the case that that feature has been disabled for security purposes.


 
Phil
Jan 16, 2009 at 4:05 pm

The HELO line is supposed to contain the fully qualified domain name of the client. Using ‘hi’ for this purpose may result in a rejection before the address can be checked.

Some mail servers, e.g. Microsoft Exchange, will accept all email for any address and then generate their own bounce if the address is invalid.


 
Adam Blinkinsop
Jan 16, 2009 at 4:37 pm

In Python, as a module and/or command line tool: gist.github.com/47987


 
Brendan
Jan 16, 2009 at 6:57 pm

It depends on how your mail server is setup. You can configure your mail server to accept any recipient and forward all mail that doesn’t match a user to a specific account.


 
Timothy
Jan 16, 2009 at 7:36 pm

Ah, this is really useful. Thanks a bunch!


 
Fenric
Jan 16, 2009 at 8:55 pm

As Capt. Sparrow mentioned with the Gmail servers, a lot more servers respond more kindly when the commands you send conform with RFC2821.

Brilliant idea, something to look into more depth. Some issues found during a couple of attempts: Gmail (At least the Google Apps servers) can take around 15 seconds to verify a domain, bit of pain but surely worth it. The larger services, Hotmail, Yahoo ect become tetchy if your servers IP doesn’t get a green light on Spamhaus.org so check your servers IP. HELO HI doesn’t always work but can be overcome with HELO as mentioned by Phil.


 
Capt. Sparrow
Jan 16, 2009 at 9:10 pm

Did anyone find any servers this trick did not work with yet?


 
Fenric
Jan 16, 2009 at 10:19 pm

Only testing from my own connection I’ve been unable to carry out the whole process on the Yahoo and Hotmail servers because I’m on a dynamic IP thus blacklisted on Spamhaus.org.

It’s coming up with a place for this function to take place on a production site. With a lot of servers responding 250 even if the mail box doesn’t exist, then further verification is still required. If you were to request the server with both the requested email and a couple of random hashs, and all requests returned 250 then it’s likely the server is accepting any recipient, in which case you would still have to send a verification email out.

Still love the idea though, anything to take that extra step out of the users registration process is a good thing.


 
jessta
Jan 16, 2009 at 11:13 pm

“what if the MX record resolves to an IP of a server thats configured to be a mail relay ?”

I’m also curious about this. Some mail servers don’t know what is and what isn’t a valid address because their job is to forward the mail to other servers that do know.
Does this still work in that case?


 
originalgeek
Jan 17, 2009 at 12:29 am

The point I think Brendan was trying to make above is that this is not a valid test that works in all situations. You will get a false 550 from some mail servers, if your MAILFROM address is unknown or is ruled to likely be SPAM by their anit-SPAM measures. Conversely, you will get false 250 responses from some servers that are configured as such. Positively acknowledging all email addresses removes a mechanism employed by spammers to discover what email addresses are valid within a domain. In my experience, I have never seen a mail server configured to not provide a positive response on a RCPT TO sent to the domain of the mail server.


 
anonymous
Jan 17, 2009 at 1:14 am

This wont work with qmail (although I believe there to be a patch so it can) due to the design. It will accept everything and bounce those that fail. There are positives and negatives for both approaches. The qmail way offers security (inability to probe for valid accounts) but at the cost of more spam as even random addresses seemingly get accepted.


 
Max
Jan 17, 2009 at 2:29 am

If you want to check to see if the email address exists, then yes this works. However some people want to check to make sure the email address is valid before they, say — open a telnet session? (This is an action which could, after all, create human-perceivable delays in the app. It is also wholly impractical for servers that would have to repeat this action hundreds of times per second.)

I am continually shocked that noone knows the correct way of validating an email address in PHP. Here’s the code:

$email = getUserEmail();
$emailIsValid = filter_var($email, FILTER_VALIDATE_EMAIL);

That’s it. It only takes one line to validate an email. It will process emails correctly according to the RFC, which means “Screw you, I’m an ant-eater!”@example.com correctly passes the filter.


 
harold
Jan 17, 2009 at 1:05 pm

Qmail (and maybe some other mailservers) will always accept mail to any local address, and later bounce that address if it can’t deliver it. It does this partly for speed, and partly it is a side effect of very strict programme design.


 
David D
Jan 19, 2009 at 5:22 pm

@Brendan
“It depends on how your mail server is setup. You can configure your mail server to accept any recipient and forward all mail that doesn’t match a user to a specific account.”

–> Can a mail server (any server such as MS Exchange) allow to forward all mails with the non-existent recipients to a specific account (as you mentioned) AND still return the error 550 5.1.1 as normal ? In other says, does the sender (from gmail for example) receive the error 550 5.1.1 after sending a mail to a mail server (Exchange for example) that has been configured to enable “forward rule” above ?


 
ev45ive
Feb 1, 2009 at 11:29 pm

There might be a problem for some users as a few SMTP servers have a thing called “SPF”
( en.wikipedia.org/wiki/Sender_Policy_Framework ) and after sending MAIL FROM: header it sends bogus like this
550 SPF Error: Please see spf.pobox.com/why.html
To ommit this You must set sender email domain to domain on wich script is fired from. Why? Because SPF checks if sender IP is the same as given e-mail domain IP.
You may try telnet to polish server mx.wp.pl to check it.

–To work around this you can easily get your IP have a reverse DNS or a PTR record from the ISP for your company domain and you will be good to go.


 
The IT Juggler
Feb 16, 2009 at 5:47 pm

This solution is great for smaller organisations, but won’t work for larger organisations that use commercial spam and virus filtering services to clean their incoming mail. The MX records get changed to point to the filtering service, which does it’s filtering magic, then forwards the email to the organisations email server.

In fact, you can setup Exchange to accept and silently delete emails that are destined for non-existent mailboxes. This is a great way to stop dictionary attacks.


 
Tero Tilus
Feb 24, 2009 at 8:22 pm

I have written a Ruby code following this article. It checks the mailbox using SMTP as mentioned above

github.com/skillnet/validates_email_with_smtp/tree/master


 
HM2K
Mar 4, 2009 at 3:11 pm

Validation is a check to ensure it is true to the specification (eg: is the number N digits long?). Not to be confused with verification which is a check to ensure it is correct within the intended system (eg: does the number work when phoned?).

This is verification, not validation.


 
Artur Ejsmont
Apr 14, 2009 at 12:37 pm

Interesting idea.

Seems too hacky for me. Checking the domain name, why not but email verification wont be reliable either way (positive/negative)

Still i like the idea itself.


 
George
Apr 14, 2009 at 6:54 pm

Thanks.

Another way you could do this is actually send the email BUT let the user login as it has already activated his account and catch bounces. If an email of a user bounces then you just mark him as inactive and force him to re-enter a valid email upon login. It requires a bit more on the server side but helps you a great deal and makes the user’s life easier.


 
John
May 1, 2009 at 1:15 pm

Spam filtering, mail forwarding systems, mail relays, MX backup handlers and more will prevent the RCPT check from working in some cases.

Also as noted above, your HELO is not a FQDN. BUT still the verification works fine in Gmail & Hotmai & few other popular mail services I have just tried.


 
PHP, Web and IT stuff » Blog Archive » Understanding FTP using raw FTP commands and telnet
May 5, 2009 at 12:48 pm

[...] FTP and SMTP are simple text based protocols. A previous article showed how to check if an email address exists using SMTP commands from the terminal. Here I would like to show you how you can use raw FTP [...]


 
Weekly Digest for May 6th : BorkWeb
May 7, 2009 at 12:04 am

[...] " How to check if an email address exists without sending an email? - PHP, Web and IT stuff — 6:46am via [...]


 
Vatar
May 20, 2009 at 9:46 pm

There are also several Web Services that can validate an email address.


 
Ashbind
May 21, 2009 at 7:26 am

Please tell me how to check Email ID existing or not in any domain.
Thanks in Advance


 
Unomi
May 21, 2009 at 1:23 pm

Hi,

I’ve used a class in PHP that does just that. I used the base from PHPClasses.org and extended the functionality a bit.

It searches for MX records and tries them, since some domains have multiple fall-back mechanisms etc. Most of the time it verifies correctly and is therefore reliable enough. I can’t distribute the code for it, since it is used within a company. But it works and indeed doesn’t take more than a second or two for each verification.

It also checks for valid HELO commands, since this is the first step to be allowed to proceed.

- Unomi -


 
Steve
Jul 7, 2009 at 9:35 pm

The “HELO” with just “hi” is screaming for problems. Please use “HELO” and a full qualified hostname and not just “hi”. btw: Be nice with the SMTPD and send a “RSET” command before the “QUIT” command.

// Steve


 
Walter Gavurnik
Jul 22, 2009 at 2:36 am

Thanks for the article. After reading all the solutions to email validation - It seems this is the BEST and most obvious way is to validate the user. With that said, can anyone tell me how to make a BCC with php. I have tried everything and it only sends to my email and not the secondary email. I figure having the user reply to the confirmation proves they want to get the reply from my contact page. Adding BCC to the email headers doesn’t work for some reason. Any help would be apreciated.


 
Bill Bartmann
Sep 2, 2009 at 7:13 am

Thanks a million!! This site rocks!


 
Mary adams
Sep 19, 2009 at 1:25 pm

I want to know if this email address is a valid one, I think I might be being scammed, if not that is good, but i need to know diplomatic@drivehq.com


 
Sofiane Edhehibi
Oct 9, 2009 at 8:28 am

Hello,

can anyone present us the implementation of this solution in VB6 ? (especially how to check if an email adress exist or not in VB 6)

Thanks,


 
Alex
Oct 22, 2009 at 11:47 am

Great, i have tested this on Gmail, yahoo mail and hotmail and it works.


 
Mr James
Oct 23, 2009 at 10:46 am

I have added this check as optional to our CRM system. :)


 
Jesen Gao
Dec 1, 2009 at 10:26 pm

Sweet.

Cheers


 
Jhon
Dec 10, 2009 at 11:06 am

Great. Now i can check the email exist or not for that particular domain.


 
Shivranjani
Dec 14, 2009 at 1:57 pm

530 5.7.0 Must issue a STARTTLS command first. 5sm1835826yxd.35

I get above exception after mail from: command. - This is for particular email accounts that need a EHLO instead of standard HELO.


 
Jakes
Jan 10, 2010 at 3:28 pm

Great. Thanks for this.


 
Carol Mill
Jan 24, 2010 at 9:05 am

Just checked this to work with Gmail & Yahoo mail accounts. Great thanks for the detailed post.


 
Alex
Feb 13, 2010 at 10:44 am

Hi! Can someone show an example with this setup in a form? I don’t really understand what I must do with these scripts to work…. I am beginner, help


 
Peter Barley
Feb 13, 2010 at 7:02 pm

Slightly diffferent subject but if I join a blog what will the people running the blog be able to tell about me, would they know where I was emailing from for example?


 
Samuel
Feb 16, 2010 at 7:21 pm

Hi I tried to use this, it worked fine for gmail, and hotmail. Thanks for sharing the code too.


 
Freddy
Feb 17, 2010 at 6:08 pm

@Alex it is pretty easy to setup. Just download the PHP files in the “SMTP check code in PHP” make sure that it is working by just following the usage example.

I got it working in a few minutes on my LAMP server.


 
arnr
Feb 25, 2010 at 3:45 pm

if i want to check vaildate mail by write programme in VB8 , from where i will start


 
LarryLove
Feb 25, 2010 at 8:07 pm

Hey very nice blog!!….I’m an instant fan, I have bookmarked you and I’ll be checking back on a regular….See ya :)


 
arnr
Feb 26, 2010 at 9:12 pm

don’t mean if the email was right when write or no , i want to check with servier or by domain name if was this email vaildate or no.


 
phuc
Mar 4, 2010 at 9:23 am

I have just tested with gmail .It seems it’s not work
telnet alt2.gmail-smtp-in.l.google.com 25
220 mx.google.com ESMTP x6si1141525gvf.28
helo hi
250 mx.google.com at your service
mail from: supermanxp2003@yahoo.com
555 5.5.2 Syntax error. x6si1141525gvf.28
mail from: supermanxp2003@yahoo.com
555 5.5.2 Syntax error. x6si1141525gvf.28

Could you help me .Thanks.Best regards


 
iphp
Mar 4, 2010 at 11:30 am

You have to use angle brackets with gmail. You will have to slightly change your instructions:
mail from: <supermanxp2003@yahoo.com> (with angle brackets)


 
phuc
Mar 5, 2010 at 6:34 am

Thanks for reply quickly .
It’s worked well for me for gmail .But i have some problem with yahoo.It required authentication login .
telnet smtp.mail.yahoo.com 25
helo hi
mail from:
Could help me this one.Thanks
Best regards


 
somxay
Mar 9, 2010 at 4:29 am

Thanks for very helpful to replied.It’s also worked well for me for livemail.


 
Govrav
Mar 15, 2010 at 9:06 am

This is used now for certain email addresses and especially valid domains that we have for the first time in our database. Works great, thanks for the code.


 
MLM Software Cochin
Mar 16, 2010 at 10:54 am

Thank you for the great information. I have been searching for this question and finally got it.


 

Reply

Copyright © 2010 PHP, Web and IT stuff All rights reserved. PHP Web development in London.