Troubleshooting

August 23, 2026 · View on GitHub

"It just hangs / times out" — your cloud provider is probably blocking the port

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:

ProviderDefault outbound SMTP behavior
AWS EC2 / LightsailPort 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 AzurePort 25 blocked on most subscription types; 587/465 generally allowed.
DigitalOceanPort 25 blocked by default for new accounts; can be requested to be lifted via support. 587/465 generally allowed.
HetznerSimilar 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 check — no credentials needed, no email sent, and the conversation stops after EHLO:

npx zerosmtp-check

Nothing to install and nothing to clone. It tests 25, 587 and 465 from the machine that is actually failing, which is the only place the answer means anything. Port 25 is included because it is the one this table is mostly about — it is checked for reachability, not as a route to send by, and the output says so.

Already have the repository checked out, or working on a box with no Node?

./check-connection.sh
./check-connection.ps1

Both live in the repository. They resolve the host, connect on 587 and 465, do the STARTTLS or implicit-TLS handshake, check whether this machine's trust store accepts the certificate, and list the AUTH mechanisms the server offers.

They work against any SMTP host, which is the point when you are trying to establish whether the problem is the server or your network — pass the hostname as an argument.

If you would rather not clone anything, the two one-liners below need nothing installed at all:

# 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.

Authentication failed

  • Confirm you copied the login/password from msgwing.com exactly — the password is shown once, right after activation.
  • Confirm your account is activated (registration alone is not enough).
  • Confirm the environment variables are actually set: a typo like 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.

Authentication failed against Microsoft 365, not against us

Everything above assumes the server refusing you is this relay. If you are still pointed at smtp.office365.com, smtp-mail.outlook.com or Gmail, the refusal is theirs and the cause is probably not your password.

Microsoft is switching off Basic authentication - username and password - for SMTP AUTH in Exchange Online at the end of December 2026. Devices and scripts that have worked for years start being refused on a day nobody touched them, with the password still correct.

Find out which it is without guessing:

npx zerosmtp-check --explain "535 5.7.139 Authentication unsuccessful"

Paste whatever your own client printed rather than what you think it means. A Postfix SASL line, a Python traceback, a code off a printer panel and curl: (67) Login denied are frequently the same refusal, and curl shows none of the server's text at all.

Three of the four causes are still reversible before the deadline, so somebody telling you to migrate today may be wrong. Check which case you are in first.

Certificate / TLS verification failed

On a printer or scanner this is usually the frozen root store rather than anything wrong: Printer cannot verify the mail server certificate.

  • Do not disable certificate verification to "fix" this (no code example in this repo does, and none should) — a cert error almost always means an intercepting proxy, an outdated system CA bundle, or a wrong hostname, not a problem with mx.msgwing.com itself.
  • Make sure you're connecting to mx.msgwing.com (not an IP address) so hostname verification succeeds.
  • Update your system's CA certificate bundle if it's very old — this is especially common on embedded devices (printers, scanners) whose firmware has a fixed, non-updatable root CA store that predates Let's Encrypt's 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.

Which port should I use?

  • 587 (STARTTLS) — the safest default; supported by nearly every SMTP client, library, and printer.
  • 465 (Implicit SSL/TLS) — use this if your client/device offers an explicit "SSL" mode separate from "STARTTLS"/"TLS", or if your network blocks STARTTLS negotiation on 587 but allows 465. Treat 465 as a fallback, not a first choice, once 587 has been confirmed to work. (An earlier version of this note cited the Canon Maxify MB2755 as a case where 587 avoided a certificate issue that 465 had — that turned out to depend on which certificate chain the server happened to be presenting at the time, not the port. See the current MB2755 write-up.)
  • 25 — not supported by ZeroSMTP for client submission, and blocked by most providers anyway (see above).

Sending limits (rate limiting)

Each ZeroSMTP account is rate-limited to keep the shared msgwing.com domain reputation high for everyone. Current limits (subject to change):

WindowSustained rateShort burst allowance
Per minute5 messages/minuteup to 20
Per hour50 messages/hourup to 100
Per day200 messages/day200 (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.

We do not offer a paid tier for high-volume or bulk sending (e.g. tens/hundreds of thousands of messages per day) — ZeroSMTP, including any future paid option, stays scoped to transactional email on the shared msgwing.com domain. For that kind of volume, use a dedicated bulk-sending platform instead; for example, EmailLabs is a Polish provider suited to that use case — a proven solution we can personally vouch for, having used it while supporting a large banking-sector company, primarily for marketing and sales email campaigns.

This project cannot receive email

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.

Still stuck?

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.