---
title: "SMTP HELO vs EHLO: What Differs and Which to Send"
description: "HELO vs EHLO in SMTP: what each command does, which hostname to send, how EHLO unlocks STARTTLS and AUTH (including OAuth 2.0), and how to debug failures."
canonical: "https://myagent.mx/blog/smtp-helo-vs-ehlo"
publishedAt: "2026-10-26T00:00:00.000Z"
updatedAt: "2026-10-26T23:09:36.557Z"
category: "deliverability"
topic: "smtp helo vs ehlo"
author: "Roshan Jonnalagadda"
authorProfile: "https://myagent.mx/blog/author/roshan-jonnalagadda"
keywords:
  - "smtp helo vs ehlo"
  - "smtp auth oauth2"
---

# SMTP HELO vs EHLO: What Differs and Which to Send

HELO vs EHLO in SMTP: what each command does, which hostname to send, how EHLO unlocks STARTTLS and AUTH (including OAuth 2.0), and how to debug failures.

![Developer testing an SMTP greeting at a terminal](/images/blog/smtp-helo-vs-ehlo/hero.svg)

Use EHLO. HELO is the original SMTP greeting and EHLO is its extended replacement: both identify the client to the server, but only EHLO lets the server list the extensions it supports, such as STARTTLS, SIZE and AUTH. [RFC 5321](https://www.rfc-editor.org/info/rfc5321/) says clients should preferentially use EHLO, and that clients and servers must still support HELO as a fallback for older implementations. This guide covers the difference, the hostname to send, the order of commands around STARTTLS and authentication, and how to debug the errors that turn up in practice.

## TL;DR

- HELO gives you basic SMTP. EHLO gives you extended SMTP (ESMTP), with a reply that lists the server's capabilities.
- Try EHLO first. Use HELO if the server does not support EHLO and your security requirements still hold.
- Send your primary host name in the greeting. If the host has no name, use an address literal.
- Once STARTTLS succeeds, send EHLO again. Encryption often changes the capabilities the server advertises, including AUTH.
- The server offers SMTP AUTH, including OAuth 2.0 mechanisms, only in its EHLO response. A HELO-only session cannot use it.

## Table of Contents

- [What HELO and EHLO actually do](#what-helo-and-ehlo-actually-do)
- [What an EHLO response looks like](#what-an-ehlo-response-looks-like)
- [Which hostname to put in the greeting](#which-hostname-to-put-in-the-greeting)
- [When to fall back to HELO](#when-to-fall-back-to-helo)
- [EHLO, STARTTLS and the second EHLO](#ehlo-starttls-and-the-second-ehlo)
- [Where SMTP AUTH and OAuth 2.0 fit in](#where-smtp-auth-and-oauth-20-fit-in)
- [Common errors and how to debug them](#common-errors-and-how-to-debug-them)
- [Our perspective: parse what the server says](#our-perspective-parse-what-the-server-says)
- [Give your agent a mailbox to test against](#give-your-agent-a-mailbox-to-test-against)
- [Related reading on ports and relays](#related-reading-on-ports-and-relays)
- [FAQ](#faq)
- [Sources](#sources)

## What HELO and EHLO actually do

Your SMTP client has to introduce itself before sending mail. [RFC 5321](https://www.rfc-editor.org/info/rfc5321/) requires an accepted HELO or EHLO before a mail transaction can begin, so `MAIL FROM` has to wait until that greeting succeeds.

The two commands differ in what they let the server say back:

| | HELO | EHLO |
|---|---|---|
| Defined for | Original SMTP | Extended SMTP (ESMTP) |
| Server reply | Single-line acceptance | Multiline 250 reply listing extensions |
| Can negotiate STARTTLS, AUTH, SIZE | No | Yes |
| Current guidance | Fallback only | Preferred |

[RFC 1651](https://www.rfc-editor.org/rfc/rfc1651.html) introduced EHLO for clients that support SMTP service extensions, recommending it in place of HELO. RFC 5321 brought that guidance into the core standard. A modern client has no reason to start with HELO.

With EHLO, the server hands you its menu of extensions. HELO gets you a seat without the menu.

## What an EHLO response looks like

EHLO succeeds with a 250 response. [RFC 1651](https://www.rfc-editor.org/rfc/rfc1651.html) describes a normally multiline reply, with the server's domain and greeting on the first line and an extension keyword, plus any parameters, on each following line.

Here is an illustrative session. The hostnames and the list of extensions are examples, not output from any particular server:

```
S: 220 mx.example.net ESMTP ready
C: EHLO client.example.org
S: 250-mx.example.net greets client.example.org
S: 250-SIZE 35882577
S: 250-8BITMIME
S: 250-STARTTLS
S: 250-AUTH PLAIN XOAUTH2
S: 250 SMTPUTF8
```

A `250` followed by a hyphen means the reply continues. Look for a space after the code on the final line to know when your parser has the whole response. Stopping after the first line is one of the most common bugs in hand-rolled SMTP clients.

Read the advertised capabilities. The [curl SMTP implementation](https://github.com/curl/curl/blob/master/lib/smtp.c) sends EHLO to initialise ESMTP and records the STARTTLS, SIZE, SMTPUTF8 and AUTH capabilities returned by the server. Those flags determine whether it proceeds with STARTTLS or authentication. Copy that behaviour and leave assumptions out of the decision.

![EHLO capabilities guide client choices](/images/blog/smtp-helo-vs-ehlo/image-2.svg)

## Which hostname to put in the greeting

The HELO or EHLO argument identifies the machine connecting to the server. [RFC 5321](https://www.rfc-editor.org/info/rfc5321/) says to use its primary host name, or an address literal when it has no name. Servers may check it. An invalid name can contribute to rejection or spam scoring.

Practical rules:

1. Use a fully qualified domain name (FQDN), such as `mail.yourcompany.com`. Bare machine names such as `localhost` and `WIN-7K2` do not qualify.
2. Check that the name resolves to an IP address. For a public sending server, check reverse DNS too: the sending IP should map back to the expected hostname, since receiving servers may assess mail using those records.
3. If the host has no name, use an address literal in square brackets. `[203.0.113.25]` is an example using a documentation address.
4. On your own SMTP server, check the outgoing greeting hostname separately from the incoming banner. Matching the two can make administration easier, though the protocol has no general requirement for them to match.

When a relay or API provider sends your mail, its servers usually connect to the recipient's server and choose the greeting seen there. Your software may choose a greeting when it connects to the relay. That greeting belongs to a separate connection.

## When to fall back to HELO

HELO is still required for compatibility. [RFC 5321](https://www.rfc-editor.org/info/rfc5321/) requires clients and servers to support the original HELO mechanisms so they can work with older conforming implementations.

The pattern in real libraries is consistent:

- The [go-smtp client](https://github.com/emersion/go-smtp/blob/v0.24.0/client.go) prefers EHLO and parses its multiline extension response. It uses HELO only if EHLO is unsupported.
- After a failed EHLO response, curl [falls back to HELO](https://github.com/curl/curl/blob/master/lib/smtp.c) only if TLS is optional or the connection is already secure.

Check that TLS condition. If your policy requires TLS and the server rejects EHLO, a fallback to HELO leaves you unable to negotiate STARTTLS, so the connection must fail rather than continue in plaintext. A HELO fallback must never silently weaken your security settings.

## EHLO, STARTTLS and the second EHLO

The sequence on a submission connection that upgrades to TLS looks like this:

1. Connect and read the server's 220 banner.
2. Send EHLO and read the extension list.
3. Check that STARTTLS is advertised.
4. Send STARTTLS and wait for the ready reply.
5. Complete the TLS handshake.
6. Send EHLO again on the encrypted connection.
7. Authenticate, then send mail.

Step 6 is easy to miss. The go-smtp client [checks that STARTTLS is advertised](https://github.com/emersion/go-smtp/blob/v0.24.0/client.go), sends the command and resets its greeting state, requiring a fresh greeting after TLS setup. Anything learned before encryption could have been tampered with along the network path, and servers commonly wait until the channel is encrypted before advertising AUTH. Skip that second EHLO and your capability list is stale. The server may refuse AUTH or return a sequence error.

Your first EHLO tells you if an encryption upgrade is advertised. An attacker on the network path may try to strip the STARTTLS line from that reply. Our [TLS vs STARTTLS policies and STRIPTLS downgrades](https://myagent.mx/blog/tls-vs-starttls) guide explains the risk and the policies used to address it. For submission port choices, see [587 vs 465](https://myagent.mx/blog/smtp-ports-587-vs-465).

## Where SMTP AUTH and OAuth 2.0 fit in

SMTP authentication comes through EHLO. [RFC 4954](https://www.rfc-editor.org/rfc/rfc4954.html) defines SMTP AUTH as an extension in which the client names an authentication mechanism, completes an authentication exchange and may negotiate a security layer for subsequent protocol interactions. The [Exim documentation](https://www.exim.org/exim-html-current/doc/html/spec_html/ch-smtp_authentication.html) describes the same sequence. Servers advertise mechanisms in the EHLO reply, then the client sends AUTH with its chosen mechanism and handles any challenges.

Two consequences follow:

- **HELO cannot authenticate.** Greet with HELO and the server never lists AUTH, leaving you with an error saying authentication is required or unavailable.
- **OAuth 2.0 tokens require a supported authentication method.** Look for XOAUTH2 or OAUTHBEARER on the server's AUTH line. Your client must support the method it selects and supply the token in that method's required format.

The Open-Xchange guide to [OAuth 2.0 with Postfix and Dovecot](https://documentation.open-xchange.com/8.22/middleware/mail/dovecot/oauth_2.0_with_postfix_and_dovecot.html) gives an example: Dovecot handles authentication through OAUTHBEARER and XOAUTH2, while Postfix reaches its authentication service over a local Unix socket. The SMTP session advertises `AUTH PLAIN XOAUTH2 OAUTHBEARER` after EHLO. Authentication ends with a 235 response.

A few details are worth knowing:

- Exim documents that successful authentication [lasts for the rest of the SMTP connection](https://www.exim.org/exim-html-current/doc/html/spec_html/ch-smtp_authentication.html). Authenticate once per connection rather than once per message.
- Check your provider's SMTP OAuth documentation for its exact XOAUTH2 string and permissions. Payload formats and required scopes vary by provider, and a token that lets you read mail through an API may lack the permission for SMTP submission.
- OAuth tokens expire. Before authenticating, check the expiry and refresh the token if needed to keep an expired token from interrupting login.

## Common errors and how to debug them

Narrow down your HELO/EHLO failure using the symptoms below. [RFC 5321](https://www.rfc-editor.org/info/rfc5321/) explains the greeting behaviour these checks rely on.

| Symptom | Likely cause | Fix |
|---|---|---|
| "Authentication required" or "must issue STARTTLS first" | Client greeted with HELO, so no extensions were offered | Send EHLO, and fall back only if it is rejected |
| Rejected greeting or bad-sequence reply | Invalid string, or a bare name that is not an FQDN | Send a real FQDN, or a bracketed address literal |
| AUTH fails after a successful STARTTLS | No second EHLO after the TLS handshake | Re-issue EHLO on the encrypted connection |
| Client tries a mechanism the server never listed | Capabilities assumed instead of parsed | Read the AUTH line and choose from it |
| Unsupported mechanism error | Server offers PLAIN and LOGIN, client only speaks XOAUTH2 | Match mechanisms, or enable the OAuth mechanism server-side |
| Authentication fails with a valid-looking token | Wrong XOAUTH2 formatting, expired token or missing scope | Rebuild the payload, refresh the token, check the provider's scopes |

A debugging routine that works:

1. Before and after STARTTLS, log the full server banner and every line of the EHLO response.
2. Check the advertised capabilities for STARTTLS and the AUTH mechanisms you expect.
3. Check that the TLS transition completed and the second EHLO was sent.
4. For OAuth, check the token's expiry and scopes. Compare the payload against the format in your provider's documentation.
5. Record the final status code, including any enhanced status code that gives further detail about the result. Our guide to [logging SMTP DSN codes verbosely](https://myagent.mx/blog/smtp-dsn-codes) explains how to read them.

If the message was accepted but delivery looks wrong, check its received headers for details of the server connections. See the [email header analyser](https://sendmux.ai/tools/email-header-analyzer).

## Our perspective: parse what the server says

We build email infrastructure for AI agents, and HELO/EHLO questions come up surprisingly often. Agents and their frameworks tend to wrap an SMTP library, so people rarely write the greeting by hand. Look at the layer above. It may assume port 587 always offers STARTTLS, attempt login before the second EHLO, or mint an OAuth token with the wrong scope and blame the greeting when it fails.

![Our perspective: parse what the server says — overview diagram](/images/blog/smtp-helo-vs-ehlo/image-3.svg)

Use the EHLO response as that connection's feature list. Capture greeting replies before and after encryption during development, then compare them to see what changed. Leave authentication payloads and tokens out of logs.

If your agent needs to receive, thread and search mail as well as send it, work through how those operations fit beyond SMTP submission. [Five checks before you migrate from SMTP to an email API](https://sendmux.ai/blog/email-deliverability/smtp-vs-email-api) gives you a migration checklist. Keeping SMTP? [RFC 5321 for developers](https://myagent.mx/blog/smtp-rfc-5321) explains the protocol requirements to build around.

## Give your agent a mailbox to test against

If you are building an agent that needs to receive mail, you can skip the sign-up. An agent can read the discovery document at `https://sendmux.ai/auth.md`, solve a proof-of-work check, register itself and hold a working `@myagent.mx` mailbox in the same session, with no human present. Pre-claim tokens can receive, read, search and thread mail straight away. Sending unlocks once a named human owner joins and approves, so the person the mail goes out under stays in control. Start at [myagent.mx](https://myagent.mx/), or see the [Sendmux agent email product](https://sendmux.ai/product) for sending, routing and per-mailbox keys.

## Related reading on ports and relays

No greeting yet? Check the port and network access if the connection fails before a greeting arrives. [587 vs 2525](https://sendmux.ai/blog/email-deliverability/587-vs-2525) compares submission options, while [port 2525 as a fallback for agent mail](https://myagent.mx/blog/smtp-port-2525) covers an alternative when the usual ports are blocked. The [comparison of SMTP relays for developers](https://sendmux.ai/blog/email-deliverability/best-smtp-relays) helps with provider selection. To read mail rather than send it, see [IMAP vs SMTP](https://myagent.mx/blog/imap-vs-smtp) for each protocol's role.

## FAQ

### Is HELO obsolete?

Not formally. [RFC 5321](https://www.rfc-editor.org/info/rfc5321/) still requires clients and servers to support it as a fallback for older implementations. In practice you should send EHLO first and use HELO only when the server rejects EHLO.

### Do I have to send EHLO again after STARTTLS?

Yes. After the TLS handshake the session state is reset, and a client such as [go-smtp](https://github.com/emersion/go-smtp/blob/v0.24.0/client.go) performs a fresh greeting on the encrypted connection. The new reply may list different capabilities, including AUTH mechanisms that were hidden before encryption.

### What hostname should I use in EHLO?

Use your primary host name as a fully qualified domain name, or an address literal if the host has no name, as [RFC 5321](https://www.rfc-editor.org/info/rfc5321/) directs. Make sure the name resolves and that your sending IP has matching reverse DNS, since receiving servers often check this.

### Does SMTP AUTH with OAuth 2.0 need EHLO?

Yes. The server advertises mechanisms such as XOAUTH2 or OAUTHBEARER on the AUTH line of its EHLO reply, as in the [Open-Xchange example session](https://documentation.open-xchange.com/8.22/middleware/mail/dovecot/oauth_2.0_with_postfix_and_dovecot.html). A client that greeted with HELO never sees that list and cannot authenticate.

## Sources

- [RFC 5321: Simple Mail Transfer Protocol](https://www.rfc-editor.org/info/rfc5321/)
- [RFC 1651: SMTP Service Extensions](https://www.rfc-editor.org/rfc/rfc1651.html)
- [RFC 4954: SMTP Service Extension for Authentication](https://www.rfc-editor.org/rfc/rfc4954.html)
- [Exim documentation: SMTP authentication](https://www.exim.org/exim-html-current/doc/html/spec_html/ch-smtp_authentication.html)
- [Open-Xchange: OAuth 2.0 with Postfix and Dovecot](https://documentation.open-xchange.com/8.22/middleware/mail/dovecot/oauth_2.0_with_postfix_and_dovecot.html)
- [curl SMTP implementation (lib/smtp.c)](https://github.com/curl/curl/blob/master/lib/smtp.c)
- [go-smtp client source (client.go, v0.24.0)](https://github.com/emersion/go-smtp/blob/v0.24.0/client.go)

## Recommended

- [SMTP Port 587 vs 2525: Which Should You Use?](https://sendmux.ai/blog/email-deliverability/587-vs-2525)
- [11 Best SMTP Relays for Developers Compared](https://sendmux.ai/blog/email-deliverability/best-smtp-relays)
- [SMTP vs Email API: Five Checks Before You Migrate](https://sendmux.ai/blog/email-deliverability/smtp-vs-email-api)
- [587 vs 465: Resolve SMTP Submission in Under 5 Minutes for Sysadmins](https://myagent.mx/blog/smtp-ports-587-vs-465)
