Inbound email operations

Port 25 failure on initial deployment

When port 25 fails during an initial inbound-mail deployment, find the earliest broken hop with measurable checks, then roll back safely.

Server rack with red X on cable and broken MX arrow on cream paper

On an initial inbound-mail deployment, port 25 connectivity failure usually means the earliest hop cannot accept SMTP from the internet—or your provider blocks outbound 25 for abuse control. Find the first failing layer with measurable checks (DNS MX, A/AAAA, listener, firewall, provider policy), fix or roll back that layer only, and keep claims scoped to what you verified. This runbook is for operators of authorized receive pipelines—not for bypassing anyone else’s filters.

Under receive email infrastructure. Mailby product inboxes already receive for you via Quick Inbox; this article is for teams standing up their own MX. We do not expose internal Mailby ops panels.

Initial deployment context and boundaries

First deploy often includes: DNS MX → load balancer → SMTP daemon → spam filter → app store.

Common confusion: cloud VMs frequently block outbound port 25 by default. That breaks sending; inbound listen on 25 is a different path but can still be firewalled. AWS and others document SMTP port restrictions—see e.g. AWS Knowledge Center on port 25 (rel="nofollow noopener") for the outbound case; apply the same “read your provider’s mail policy” habit for inbound security groups.

Boundaries:

  • Authorized systems only.
  • No open relay. Receive-only or authenticated submit.
  • Temporary consumer inboxes are not a substitute for fixing MX—but developers can help app tests while infra is down.

Field demonstration (editorial, 2026-09-24)

Working path: New VM security group allows TCP 25 from 0.0.0.0/0 (or preferred smarthost ranges); ss -ltn shows :25; external nc -vz mx.example 25 gets SMTP banner; MX points to correct A record.

Failure path: MX correct, local daemon listens on 127.0.0.1:25 only. External connect times out. Earliest failing hop: bind address / firewall—not DNS.

Limitation: we cannot reproduce every cloud image; always capture your own tcpdump/nc evidence.

Mechanism

Traffic path: sender MTA → your MX host:25 → daemon → pipeline.

Failures:

  1. MX / A mismatch
  2. No process on 25
  3. Bound to localhost
  4. Security group / nftables drop
  5. Provider network ACL
  6. TLS-only misconfig rejecting clear banner probes (less common on first hop)

Layer table

LayerCheckExpected observationFailure clueRollback
DNS MXdig MX example.comPriority → intended hostWrong host / no MXRestore prior MX TTL
Addressdig A mxhostPublic IP of boxStale IPFix A/AAAA
Listenerss -ltn | grep :25LISTEN on 0.0.0.0 or ::Missing / localhost onlyRestart with correct bind
FirewallCloud SG + host fwAllow 25/tcpTimeout no bannerRevert SG rule
Bannernc -vz host 25220 responseTimeout/RSTPrevious AMI / LB
App storeSend test messageQueued in appAccepted then droppedDisable new filter rule

Worked example

Deploy checklist:

  1. Snapshot DNS records before change.
  2. Bring up daemon on staging IP; verify banner externally.
  3. Lower MX TTL beforehand; swap MX.
  4. Send test from an external account you control.
  5. If port 25 blocked by cloud policy, open a support request or use a relay/inbound provider—do not “clever” tunnel around ToS.

While infra is broken: developers can still validate app templates with Laravel mail tests and manual inbox receives.

Alternatives

  • Managed inbound (Postmark inbound, SES receipt rules, etc.)
  • Mailby for product/QA receive without self-hosting MX
  • Dual-MX with vendor backup during cutover

Short answers

What causes port 25 connectivity failure on initial deployment?
DNS mistakes, bind/firewall issues, or provider blocks—verify in that order.

What should I do first?
External banner check to the MX host; then ss and security groups.

When is a permanent address safer?
Irrelevant to ops MX—but user-facing recovery still needs durable mailboxes.

What evidence changes the recommendation?
Banner OK but app empty → shift diagnosis to filtering/storage, not port 25.

Sources, test date, limitations

  • Runbook date 2026-09-24.
  • Provider example: AWS port 25 guidance.
  • SMTP base: RFC 5321.
  • Limitation: legal/ToS constraints on mail ports vary by host.

Outbound versus inbound: stop mixing the symptoms

Teams often paste “port 25 blocked” from a sending blog while debugging inbound MX. Clarify:

  • Outbound 25 — your app or MTA cannot send to the world (common cloud throttle).
  • Inbound 25 — the world cannot deliver to your MX listener.

Fixes differ. Outbound may require provider approval or a submission port (587) to a smarthost. Inbound needs public listen + DNS. Applying an outbound ticket to an inbound outage loses a day.

Load balancers and PROXY protocol surprises

If SMTP sits behind an L4 load balancer, health checks must speak SMTP or TCP correctly. Misconfigured health checks flap backends; external nc sometimes succeeds to the VIP while sessions reset mid-DATA. Capture packet timelines before blaming Postfix configs.

IPv6 partial deploys

MX returns AAAA, but the daemon listens only on IPv4. Some senders prefer AAAA and fail; others succeed on A. Symptom: “intermittent delivery.” Check both stacks with nc -vz on each address family.

How this differs from the receive-email-infrastructure hub

The hub describes architecture options. This runbook is a first-deploy port 25 diagnosis with layer table and rollback column. It refuses to disclose Mailby internal panels; use public product receive instead when you do not want to operate MX.

Safe rollback drill

Practice once on staging:

  1. Lower TTL days before cutover.
  2. Keep previous MX host warm.
  3. On failure, switch MX back before changing code.
  4. Only then iterate firewall/daemon.

DNS mistakes propagate longer than process restarts. TTL discipline is the real rollback mechanism.

Observability minimum viable set

  • External synthetic: banner check every minute
  • Internal: queue depth after accept
  • Alert: zero accepts after MX change
  • Log: reject codes with categories (policy, space, virus)

Without synthetics, users become your monitors—usually on launch day.

When not to self-host inbound

If the business need is “see OTPs for our SaaS,” prefer app-level testing and developers rather than standing MX on a single VM. Self-host when inbound mail is the product or a regulated requirement—not as a weekend detour.

TLS on port 25 versus submission

STARTTLS on 25 is common for MTA-to-MTA. Do not confuse it with client submission on 587. First-deploy banner checks can use cleartext 220 responses; deeper tests should negotiate STARTTLS and verify certificates match the MX hostname. Certificate mismatches cause silent sender deferrals that look like “connectivity” while TCP works.

Greylisting during cutover

New MX hosts may greylist unknown senders, delaying first messages. Coordinate with monitoring so greylisting is not paged as port failure. Document expected first-delivery delay in the runbook.

Capacity and accept rates

Port open ≠ ready for production volumes. Load-test SMTP accepts before MX cutover. A single-threaded debug daemon will pass nc and fall over under real senders.

Packet capture etiquette

Capture on the MX host with filters for port 25 only, time-box to five minutes, and avoid retaining payloads longer than needed. Redact in tickets. Connectivity diagnosis rarely needs DATA-phase content—banner and TCP handshake usually suffice.

Multi-homed hosts

Servers with multiple NICs may bind SMTP to an internal interface while DNS points to a public IP. ss shows LISTEN, external nc times out. Confirm the listen address matches the announced IP. Container port publishes (-p 25:25) fail the same way when forgotten.

Change management template

Change: MX cutover to mx2
Checks before: dig, ss, nc banner, synthetic send
Checks after: same + accept logs non-zero
Rollback: MX back to mx1 within 15 minutes if synthetic fails
Owner: @oncall

Paste into the incident channel before you start. Improvisation is how TTL mistakes become weekend work.

Relationship to product receive

If your actual goal is temporary addresses for customers or QA, do not build MX—use inbox / developers. This runbook is for teams who truly must accept mail at their domain.

DNSSEC and middlebox failures

Rare but ugly: DNSSEC misconfiguration makes MX lookups fail for validating resolvers while your laptop’s resolver succeeds. Test with a validating resolver or online DNSSEC checkers before blaming firewalls. Middleboxes that “helpfully” proxy SMTP can also break STARTTLS—compare paths on and off corporate VPN.

Runbook ownership

Assign a primary and secondary owner. Store the layer table in the ops wiki with last-exercised date. A runbook never practiced is fiction; schedule a quarterly game day that intentionally breaks staging port 25 and times the recovery.

SELinux and container capabilities

Hardened hosts may deny bind to 25 without policies. Check audit logs when ss shows nothing after a “successful” start. Containers may need NET_BIND_SERVICE or an explicit port map. These failures present exactly like “cloud blocked 25” until you read the audit line.

Appendix: quick command strip

dig +short MX example.com
dig +short A mx.example.com
ss -ltn | grep ':25'
nc -vz mx.example.com 25
sudo tcpdump -ni eth0 port 25 -c 20

Run in order. Stop at first unexpected result. Paste outputs into the incident thread with timestamps. This strip is deliberately boring; boring restores mail.

Post-incident review prompts

  • Which layer failed first, really?
  • Did TTL planning save us or slow us?
  • Were synthetics loud enough?
  • Did anyone “fix” the wrong plane (outbound vs inbound)?
  • What single checklist line would have caught it in five minutes?

Write answers within 48 hours while memory is fresh. Update the layer table. Then schedule the next game day so the update is practiced, not only filed.

Coordination with security teams

Opening port 25 invites scanners within minutes. Tell security before the SG change, enable rate limits and banner greylisting as policy allows, and monitor for open-relay tests. An inbound receive pipeline that accidentally relays outbound will get your IP blacklisted—connectivity “success” followed by reputation failure. Keep relay disabled; verify with explicit anti-relay tests in the deploy checklist.

Conclusion

Port 25 failures are earliest-hop problems until proven otherwise. Measure DNS, listen, firewall, banner—then roll back the last change. Self-host only if you need to; otherwise ship product mail tests via developers and user trials via inbox while infrastructure stabilizes.

Try it on Mailby

Open a receive-only disposable inbox when a short-lived address fits the job — session-bound, with timed purge.