NetSendo v2.11.0: Built-In MTA, Port 25 & PTR Checks
Running your own mail server comes with some well-known problems. Your hosting provider may block outbound port 25 without telling you. Your server's IP may have no reverse DNS (PTR) record. Your SPF record may not list the IP your mail actually leaves from. Any one of these can send your emails to spam, or leave them stuck in a queue.
NetSendo v2.11.0 deals with all of this. The NetSendo MTA now ships with every installation as a standard service. It also checks its own setup the way a receiving mail server would, and tells you exactly what to fix.
nmi-mta) is part of the default docker-compose.yml and uses a published image. It relays mail for GOLD installations. A new "Can this server send mail" panel checks outbound port 25, your PTR record and your SPF entry. The MTA now uses your server's PTR name in HELO, and the SPF checks look for ip4:/ip6: instead of an include: that never worked.
🚀 What's New in v2.11.0
The MTA Is Now a Standard Service
Before this release, the MTA container started only with docker compose --profile nmi. It was built on your server from files that install.sh never downloaded. The provider was also hidden unless NMI_ENABLED=true was set, and no installation had that setting. In practice, almost nobody could use it.
Now the MTA works like any other NetSendo service:
- It's defined in
docker-compose.ymland starts with everything else - It uses a published image,
ghcr.io/netsendo/netsendo:mta-<version>, built by the same workflow as the app - Its configuration and plugins are inside the image, so nothing is mounted from your installation folder
- It publishes no ports on the host, so several installations on one server no longer clash on 2525/2587
The NetSendo MTA provider appears in Settings → Mailboxes whenever the MTA responds. Without GOLD, the provider shows a GOLD badge. The MTA relays nothing until a GOLD installation saves a mailbox with this provider, because it only accepts sessions that log in with credentials NetSendo issued.
⚠️ Important:NMI_ENABLEDis no longer read..envfiles copied from older examples containNMI_ENABLED=falseeven though nobody chose that value. To opt out, useNMI_DISABLED=trueinstead. This hides the provider and stops NMI's scheduled jobs.
# .env — optional NMI settings
NMI_DISABLED=true # hide the provider and stop NMI scheduled jobs
NMI_MTA_HOST=nmi-mta # service name the app uses to reach the MTA
NMI_HELO_HOST=mail.example.com # override the HELO name (optional)
NMI_EGRESS_PROBE=false # turn off the outbound check (optional)
The app reaches the MTA by its service name, nmi-mta. The old name, netsendo-mta, keeps working for as long as the container uses it.
"Can This Server Send Mail?"
This check appears in the NetSendo MTA section of the mailbox form and in Settings → Mail Infrastructure. The MTA runs it on startup and again every few hours. It tests from the outside, the way a receiving server sees you: it connects to a Gmail MX on port 25, sends nothing, and reads back the address the MX reports for you.
Outbound Port 25
Shows whether port 25 is open or blocked by your provider. If it's blocked, mail would stay in the queue, and the panel tells you what to do.
Public IP & PTR
Shows your public address, its PTR record, and whether the PTR name resolves back to the same address.
SPF Entry
Gives you the exact ip4:… entry to add to your sending domain's SPF record, with a copy button.
HELO Uses Your Server's PTR Name
Mail sent without a dedicated IP used to introduce itself in HELO with the container's hostname, which no receiver can resolve. Now, if your public IP's PTR points to a hostname that resolves back to that IP, the MTA uses that hostname. Think of it as giving a real return address instead of a room number inside the building. NMI_HELO_HOST still overrides this if you need to.
Corrected SPF Checks
Deliverability checks used to ask for include:_spf.<installation host>, a record nobody publishes. They now look for your server's public IP, or the mailbox's dedicated IP, as an ip4:/ip6: entry, including ranges. You get a warning if it's missing, and the generated record adds it:
example.com. TXT "v=spf1 include:_spf.google.com ip4:203.0.113.10 ~all"
💼 Benefits & Use Cases
E-commerce: Reliable Transactional Mail
Abandoned cart reminders and order confirmations need to arrive on time. With port 25, PTR and SPF checked before you go live:
- You learn about a blocked port before cart emails sit in a queue
- Post-purchase sequences go out with matching PTR, HELO and SPF
- No per-email fees from a third-party relay
SaaS: Onboarding That Reaches the Inbox
Onboarding and churn-prevention emails only work if users see them. The built-in MTA keeps the whole sending path on your own infrastructure, and the regular re-checks catch DNS or network changes before they affect deliverability.
Agencies: Several Installations on One Host
Because the MTA no longer publishes ports, you can run separate NetSendo installations for different clients on the same server without conflicts on 2525/2587. Each client keeps its own data and configuration.
🛠️ Step-by-Step Upgrade Guide
-
Get the New Compose File
Replace your
docker-compose.ymlwith the v2.11.0 version. It adds thenmi-mtaservice and thenmi-*volumes. -
Clean Up
.envRemove
NMI_ENABLED. If you don't want the MTA at all, addNMI_DISABLED=true. -
Pull and Restart
docker compose pull && docker compose up -dIf you used to run the MTA with
--profile nmiand--build, stop using both flags. The service now runs from the published image. -
Review the Sending Check
Open Settings → Mail Infrastructure. You'll see the status of port 25, your public IP and PTR, and the SPF entry you need.
-
Fix PTR and SPF
Set the PTR in your hosting provider's panel, then copy the
ip4:entry into your domain's existing SPF record. Don't create a second SPF record. -
Create a Mailbox (GOLD)
In Settings → Mailboxes, choose NetSendo MTA and save. The MTA starts relaying once this mailbox exists.
ℹ️ Note: If you keep your old compose file, the installation still works. The mailbox form will simply report that the MTA isn't responding.
Common Pitfalls
- Port 25 blocked: Many cloud providers block it by default. The new guide in
docs/NMI.mdcovers Google Cloud, AWS, Azure, DigitalOcean, Hetzner, Vultr, Linode, OVHcloud and Contabo. - Two SPF records: A domain can have only one. Add the
ip4:entry to the record you already have. - PTR without forward DNS: The PTR hostname must also have an A/AAAA record that points back to the same IP.
🎯 Expert Tips
Run dig -x 203.0.113.10 +short, then dig A on the hostname it returns. Both should match, which is what the panel checks.
ip4: entries don't count toward SPF's 10-DNS-lookup limit, so they're a good way to authorize your server.
The probe re-runs every few hours and catches changes such as a new IP or a provider policy change. Only set NMI_EGRESS_PROBE=false if outbound checks aren't allowed on your network.
With no published host ports and authentication limited to credentials NetSendo issues, the MTA can't be used as an open relay. Keep it that way: don't add port mappings to the service.
🎉 Conclusion
NetSendo v2.11.0 makes self-hosted sending much easier to set up. The MTA ships with every installation, runs from a tested image, and tells you whether your server can actually deliver mail. Correct SPF guidance and PTR-based HELO give your emails a better chance of reaching the inbox, all on infrastructure you own.
Ready to Send From Your Own Server?
Upgrade to v2.11.0 and run the new sending check today:
Explore more integrations and ⭐ star us on GitHub.


