# How to Check if an Email Address Exists (Without Sending an Email)

To check whether an email address exists without sending a message, ask the mail server for its domain. You look up the domain's mail server, connect to it, and name the address with the `RCPT TO` command. The server answers yes or no before any message is sent. That answer is evidence, not proof: some servers say yes to every address, and some do not answer at all.

This is also what people mean by "pinging" an email address. There is no ping for a mailbox. The closest thing is asking the server this one question.

## The short version

1. Check the address is written correctly.
2. Look up the domain's mail servers (its MX records). A domain that accepts no mail has no mailboxes.
3. Connect to the mail server and ask whether it accepts the address.
4. Read the reply: accepted, rejected, or no clear answer.

A validation service does all four in one call. You can also do it by hand for a single address. If you do not want a terminal, the last section shows how to check one address in a dashboard.

## Doing it by hand

**Find the mail server.** In a terminal:

```sh
dig +short MX gmail.com
```

On Windows, `nslookup -type=MX gmail.com` does the same. You get a list of servers with priorities. If the only line is `0 .`, the domain has published a null MX, a record that says it accepts no mail, and you can stop. If the list is empty, the domain may still take mail at its own name, so use the domain itself as the server.

**Ask the server.** Connect to the server with the lowest number, on port 25, the port mail servers use to talk to each other:

```sh
telnet gmail-smtp-in.l.google.com 25
```

If `telnet` is not installed, `nc` works in its place. Wait for the server's `220` greeting, then type these lines one at a time:

```
EHLO yourdomain.example
MAIL FROM:<you@yourdomain.example>
RCPT TO:<the-address-you-are-checking@gmail.com>
QUIT
```

Replace `yourdomain.example` and `you@yourdomain.example` with a real domain and address of your own. The server replies to each line with a three-digit code. The reply to `RCPT TO` is the one you want. Stop there and type `QUIT`. Do not type `DATA`: that is the command that starts a real message.

Two things often get in the way. Many home and cloud networks block outgoing connections on port 25, so the first line may simply hang. And some servers refuse or defer senders they do not recognise, so the answer you get from your laptop may not be the answer a real sender would get.

Do this for one address. Do not script it over a list from your own mail server: repeated `RCPT TO` with no message looks like address harvesting and can get the IP blocked.

## What three servers actually said

These are real replies to `RCPT TO`, from a test set we ran through PingValid on 2 October 2026. It is a constructed set, built to show one case per row. No accuracy figure can be drawn from it.

| Address asked about | The server's reply | What it means |
|---|---|---|
| A made-up mailbox at `gmail.com` | "550 5.1.1 The email account that you tried to reach does not exist." (first sentence of the reply) | The mailbox does not exist. |
| `test@mailinator.com` | `250`, accepted | The server accepted the address. The domain is a public throwaway inbox service. |
| A made-up mailbox at `pingvalid.com` | `250`, accepted | Nothing. That mailbox does not exist; our own domain accepts mail for any address. |

Two more addresses never got as far as a mail server. `test@example.com` stopped at the MX lookup: "Null MX (RFC 7505): example.com does not accept mail." `user@mail.example.invalid` stopped one step earlier: the domain has no address in DNS.

## Reading a reply you got by hand

- **`250`:** the server accepted the address at that moment. That is evidence the mailbox exists, not proof.
- **A 5xx code such as `550`:** a permanent refusal. Read the text after the code. `5.1.1` or "does not exist" means no such mailbox. `5.7.1`, or a mention of policy, a blocklist or your IP address, means the server refused you as a sender and has said nothing about the mailbox.
- **A 4xx code, or no answer:** the server did not decide. Try again later.

[SMTP error codes explained](/blog/smtp-error-codes-explained) covers each code, and [what an SMTP check is](/blog/smtp-check-explained) covers how the probe works.

## When no check can tell you

**Catch-all domains.** Some domains accept mail for any address. Their server says `250` to a real mailbox and to a made-up one. The third row above is that case.

PingValid has three tiers: Quick stops before the mail-server check, Standard includes it, and Deep adds catch-all detection. On Standard, that made-up address came back `valid`, risk score 0, because Standard does not test for catch-all. On Deep it came back `risky`, with the reason "Domain pingvalid.com accepts arbitrary addresses (catch-all)." Deep needs a paid plan or a top-up.

Knowing a domain is catch-all still does not tell you which of its mailboxes are real. [SMTP error codes explained](/blog/smtp-error-codes-explained) covers how the detection works.

**Servers that do not answer.** A server can ask you to retry later or not respond. PingValid returns `unknown` for an inconclusive check on an otherwise clean address, and does not charge for it. [Why a verifier says "unknown"](/blog/why-email-verifier-says-unknown) covers the causes.

## "Exists" is not the same as "safe to send"

The second row is the example. The mail server accepted `test@mailinator.com`. PingValid still returned `invalid`, because the domain gives out throwaway addresses. A shared mailbox is similar: in the same test set `postmaster@cloudflare.com` was accepted by its server and came back `risky`, because it is a role account, not one person's mailbox.

So "does it exist?" is one check among several, and PingValid returns one verdict from all of them: `valid`, `risky`, `invalid` or `unknown`. [What an SMTP check is](/blog/smtp-check-explained) lists the checks in order.

Two things no check covers. It does not tell you whether you have permission to email the address. And it describes the address at the time of the check; it is not a promise about where a later message lands.

## Can a check be wrong?

Yes. On a catch-all domain a missing mailbox can pass: on the Standard tier our made-up address at `pingvalid.com` came back `valid`. A server that refuses the sender, not the mailbox, still produces a refusal. And a mailbox can be closed after the check.

## Why not just send a test email?

Because it is a real message to a real person, and if the address is bad you get a bounce on your own sending record. Asking the server first delivers nothing to the recipient.

## Checking one address, a list, or every signup

- **One address.** Check it in the PingValid dashboard (leave the tier on Standard), or use the [API](/docs/api). One check uses 1 credit on Quick or Standard and 2 on Deep.
- **A list.** Upload a CSV and get a verdict for every address. See [email list cleaning](/use-cases/email-list-cleaning).
- **Every new signup.** Call the API before the account is created. See [how to stop fake signups](/blog/stop-fake-signups-saas).
- **From Claude.** Add PingValid as a connector and ask in plain words. See the [guide to the Claude connector](/blog/email-validation-mcp-server).

A free PingValid account comes with 100 validations a month on the Quick and Standard tiers and needs no card. The Deep tier needs a paid plan or a top-up. Plans are on the [pricing page](/pricing).