This is, by far, the most common reason a first attempt fails, and it has nothing to do with ZeroSMTP configuration. Many cloud and hosting providers block outbound SMTP ports by default on new accounts, specifically to fight spam:
| Provider | Default outbound SMTP behavior |
|---|---|
| AWS EC2 / Lightsail | Port 25 blocked by default on all accounts; a support ticket (“EC2 email sending limit removal”) is required to lift it. Ports 587/465 are generally not blocked. |
| Google Cloud (GCE) | Port 25 blocked; 587/465 generally allowed. |
| Microsoft Azure | Port 25 blocked on most subscription types; 587/465 generally allowed. |
| DigitalOcean | Port 25 blocked by default for new accounts; can be requested to be lifted via support. 587/465 generally allowed. |
| Hetzner | Similar default restrictions on port 25; open a support ticket if outbound mail is core to your use case. |
| Home / office network (ISP) | Residential ISPs very commonly block outbound 25, and sometimes 587, to stop compromised machines from spamming. Check your ISP’s Acceptable Use Policy. |
This is why every example in this repository defaults to port 465
(implicit SSL/TLS) or 587 (STARTTLS), never port 25. If a script hangs
until it times out rather than failing immediately, this is the first thing
to check. Run the connectivity-only healthcheck (no credentials needed, no
email sent):
./check-connection.sh
./check-connection.ps1
Or check manually:
# Bash/Linux/macOS — quick manual connectivity check
curl -v --connect-timeout 10 telnet://mx.msgwing.com:587
curl -v --connect-timeout 10 telnet://mx.msgwing.com:465
# Windows PowerShell
Test-NetConnection -ComputerName mx.msgwing.com -Port 587
Test-NetConnection -ComputerName mx.msgwing.com -Port 465
If both time out from a cloud VM but work from your home network, contact your provider’s support to unblock outbound SMTP for your account/instance.
USERNAME
instead of ZEROSMTP_USERNAME will silently fall back to a placeholder
value or (on Windows) your OS login name — see the note in
.env.example.mx.msgwing.com itself.mx.msgwing.com (not an IP address) so
hostname verification succeeds.ISRG Root X1 root. One confirmed case is documented in
PRINTERS.md
(Canon Maxify MB2755) — treat disabling verification as a last resort for
that specific class of device, not a general fix.Each ZeroSMTP account is rate-limited to keep the shared msgwing.com
domain reputation high for everyone. Current limits (subject to change):
| Window | Sustained rate | Short burst allowance |
|---|---|---|
| Per minute | 5 messages/minute | up to 20 |
| Per hour | 50 messages/hour | up to 100 |
| Per day | 200 messages/day | 200 (hard cap, no extra burst) |
Additionally, a single message can address at most 15 recipients (To + Cc + Bcc combined).
If you hit a limit, the server will reject or temp-fail the send — treat that the same as any other transient SMTP error: back off and retry later rather than looping immediately (see RELIABILITY.md). These limits are sized for typical transactional use (notifications, password resets, contact forms, scan-to-email); if your application needs sustained volume above them, contact abuse@msgwing.com before you build around it.
ZeroSMTP is outgoing-only: there is no inbox, IMAP, or POP3 access tied to a
@msgwing.com account. If a test message doesn’t “come back”, that’s
expected — send it to a mailbox you actually control (e.g. your personal
email, or a service like mail-tester.com) to
verify delivery, as shown in
SendEmailTest_mail-tester.com.ps1.
Contact abuse@msgwing.com, or open an issue on this repository with: the language/example you’re using, the exact error message, and which port you tried.