Email·8 min read·

PTR, HELO, and Matching the SMTP Hostname

Receivers reject mail when PTR, HELO, and the A record disagree. Align the hostname, reverse DNS, and Postfix myhostname before you send mail.

NB

Netbay Developer Relations

Netbay Engineering

On this page

Forward-confirmed reverse DNS is the first identity check a receiving MX runs, and it is the check most VPS mail setups fail. The connecting IP must reverse to a name, that name must forward back to the same IP, and the SMTP HELO string should be that same name. When those three disagree, Gmail and Outlook treat the session as forged even if SPF later passes.

The three names that must agree

Call the public address of the VPS 203.0.113.40. You need one hostname, not three stories.

  • A (or AAAA) record: mail.example.com points at 203.0.113.40.
  • PTR record: 203.0.113.40 reverses to mail.example.com.
  • HELO/EHLO: Postfix announces mail.example.com, not localhost, not ubuntu, not the default Debian name.

The PTR is not a record you publish in your domain zone. Reverse DNS for a public IP lives in the address owner's in-addr.arpa (or ip6.arpa) zone. On a VPS that means you request it from the host. Netbay assigns a static IP in Lucknow DC01; ask support to set the PTR to the hostname you actually HELO as. Do not invent a second hostname "because the panel default looks ugly." Pick one FQDN and use it everywhere.

FCrDNS identity triangle A record mail.example.com PTR record 203.0.113.40 HELO name smtp banner same FQDN on all three mismatch here is a reject before SPF

Set the machine hostname first

The OS hostname leaks into HELO if Postfix is left on defaults. Set a real FQDN, not a short name.

bash
hostnamectl set-hostname mail.example.com
cat /etc/hosts
# 203.0.113.40  mail.example.com mail
hostname -f
getent hosts mail.example.com

hostname -f must print mail.example.com. If it prints localhost or a name that does not resolve, Postfix will HELO as that garbage. Many "works on mail-tester then fails at Outlook" tickets are this one line.

Teach Postfix the same name

myhostname is the HELO string. mydestination should not swallow mail for the public domain if this box is only a sender. smtpd_banner is cosmetic but receivers do log it.

ini
# /etc/postfix/main.cf
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = loopback-only
mydestination = $myhostname, localhost.$mydomain, localhost
smtp_helo_name = $myhostname
smtpd_banner = $myhostname ESMTP
smtp_host_lookup = dns

inet_interfaces = loopback-only is the right default when this VPS only submits outbound mail from local apps. Do not expose port 25 to the world unless you intend to receive. After the edit, run postfix reload and confirm the banner:

Verify with openssl s_client or a manual EHLO. The first line of the remote trace should show EHLO mail.example.com, not EHLO localhost.localdomain.

Confirm the triangle from outside

Do not trust the box you are sending from. Check from a second host, or from a lookup site that is not your own resolver cache.

  • dig -x 203.0.113.40 should return mail.example.com with a trailing dot.
  • dig mail.example.com A should return 203.0.113.40.
  • The names must match character for character. mail.example.com and smtp.example.com are different identities.

TTL matters. A PTR change can take hours to be visible to Gmail. Send test mail after you see the new PTR from a public resolver, not after the ticket is marked done.

Common mismatch patterns

The Debian installer leaves the hostname as ubuntu or debian. Cloud-init sometimes writes a name based on the instance id. Postfix then HELO as that string. Microsoft in particular is unforgiving: 5.7.606 or 5.7.511 Access denied, with a hint about reverse DNS, is this class of bug.

Another pattern: you set the PTR to example.com (the naked domain) while Postfix HELO as mail.example.com. Naked-domain PTRs fail FCrDNS because the A record for example.com often points at a CDN or the web VPS, not the mail IP. Give the mail role its own hostname.

IPv6 has the same rules on ip6.arpa. If the VPS has an AAAA and Postfix listens on IPv6, the IPv6 PTR must match too. If you cannot set an IPv6 PTR, prefer sending over IPv4 only (inet_protocols = ipv4) rather than presenting an unmatched AAAA.

Takeaway

PTR, HELO, and the A record are one identity. Pick a single FQDN, put it in /etc/hosts, main.cf, and the reverse DNS request, then verify from a public resolver. You can spin up an Ubuntu 24.04 instance on Netbay in under 60 seconds, set the hostname, and request a matching PTR on the static Lucknow IP — netbayhosts.in.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance