You can debug SMTP server connections manually using Telnet by opening a direct, unencrypted TCP connection to the mail server and issuing SMTP commands yourself.

Here’s how you can simulate sending an email, step-by-step, to see exactly where things might be going wrong.

Let’s connect to a hypothetical mail server, mail.example.com, on its standard SMTP port, 25.

telnet mail.example.com 25

If the connection is successful, you’ll see a banner from the server, usually indicating the server software and version. It might look something like this:

220 mail.example.com ESMTP Postfix

The 220 is a status code meaning "Service ready." This tells you the server is listening and potentially willing to accept connections.

Next, you need to introduce yourself. This is done with the HELO (or EHLO for extended HELO) command. EHLO is generally preferred as it allows the server to tell you what extensions it supports.

EHLO yourdomain.com

Replace yourdomain.com with a domain that the server might recognize, or just your own. The server will respond with a list of capabilities. A successful response might look like this:

250-mail.example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

The 250 status code means "Requested mail action okay; completed." The lines following indicate features like SIZE (maximum email size), STARTTLS (support for encrypted connections), and others. If you get a 5xx error here, the server is rejecting your initial greeting, which could be due to IP blocking, greylisting, or misconfiguration on your end.

Now, let’s specify the sender of the email. This is done with the MAIL FROM: command.

MAIL FROM: sender@yourdomain.com

Again, use an email address that makes sense in context. A typical successful response is:

250 2.1.0 Ok

The 2.1.0 is an enhanced status code indicating "Other address status: informational success." If you see a 5xx error here, the server might be rejecting the sender address based on its policies (e.g., it doesn’t expect mail from your domain, or the address itself is invalid according to its checks).

Next, you tell the server who the recipient is using the RCPT TO: command. You can specify multiple recipients by issuing this command multiple times.

RCPT TO: recipient@example.com

A successful response:

250 2.1.5 Ok

The 2.1.5 status code means "Other address status: informational success." A 5xx error here is crucial: it means the server does not accept mail for that specific recipient. This could be because the recipient doesn’t exist on that server, or the server is configured to reject mail for certain domains or addresses. This is a common place for delivery failures.

Once you’ve specified the sender and recipient(s), you signal that you’re ready to send the email data with the DATA command.

DATA

The server will respond with a code indicating it’s ready to receive the message body.

354 Start mail input; end with <CRLF>.<CRLF>

The 354 status code means "Start mail input; end with .." This is your cue to type the email content. The email must be properly formatted with headers (like Subject:, To:, From:) followed by a blank line, and then the body of your message.

To send the email, you must end the DATA section with a line containing only a period (.) followed by a carriage return and line feed (<CRLF>).

Here’s an example of what you might type after the 354 response:

Subject: Test Email from Telnet
From: sender@yourdomain.com
To: recipient@example.com

This is the body of the test email.
It's being sent directly via SMTP.
.

After you type the final ., the server will process the email. A successful delivery attempt will result in:

250 2.0.0 Ok: queued as ABCDEF12345

The 2.0.0 status code means "Other status: informational success." The queued as... part indicates the mail server has accepted the message and placed it in its queue for delivery. If you get a 5xx error here, it means the server rejected the entire message after you sent it, perhaps due to content filtering, spam checks, or size limits that weren’t caught earlier.

Finally, to close the connection gracefully, you use the QUIT command.

QUIT

The server will respond with a 221 status code, meaning "Service closing transmission channel."

221 2.0.0 Bye

This entire process, from connecting to QUIT, allows you to isolate connection issues. If telnet mail.example.com 25 fails, the problem is at the network level or the server isn’t running. If EHLO fails, it’s an initial server greeting issue. If RCPT TO fails for a valid recipient, the server is actively rejecting mail for that address. If DATA fails, it’s a content or policy issue.

The next thing you’ll run into is understanding SMTP authentication, as most modern mail servers require it for sending mail.

Want structured learning?

Take the full Smtp course →