If your server can't send email, check port 25 first. Most cloud providers block outbound port 25 by default, so a VPS can't hand mail directly to Gmail, Outlook or Yahoo. Run nc -vz -w 5 gmail-smtp-in.l.google.com 25 on the server. If it times out, the port is blocked. You then have three ways out: ask your provider to lift the block, relay through an authenticated SMTP service on port 587, or send through an email API over HTTPS.

Below are the policies for Hetzner, AWS, Azure, DigitalOcean and Contabo as of October 2026, taken from each provider's own documentation where it exists. Providers change these rules, so check the linked page before you plan around them.

Why providers block port 25

Port 25 is how mail servers deliver to each other. A spammer who rents a cheap VPS, or breaks into one, uses port 25 to hand junk straight to Gmail. When that happens, the provider's IP ranges end up on blocklists and every customer suffers. Blocking outbound 25 by default, and opening it only for customers with some history, is the cheapest defence.

This is why the block usually covers port 25, and sometimes 465, but rarely 587. Ports 587 and 465 are for submission: you log in to a mail server with a username and password, and that server delivers for you. Submission needs an account somewhere, which makes it much less attractive for abuse.

How to test if port 25 is blocked

Test from the server, not from your laptop. Home internet providers often block port 25 too, so a test from home tells you nothing about the VPS.

# Outbound port 25 to Gmail's inbound servers
nc -vz -w 5 gmail-smtp-in.l.google.com 25

# Submission ports, for comparison
nc -vz -w 5 smtp.ownmailserver.com 587

How to read the result:

Result What it means
succeeded / open Outbound port 25 works
Hangs, then times out Traffic is dropped, almost always a provider or firewall block
Connection refused You reached a host that refused, so the path is open; try another mail server

If you get a timeout, rule out your own firewall before blaming the provider. Check ufw status or nft list ruleset on the server, and any cloud firewall or security group attached to it. Outbound rules there are easy to forget because they rarely matter for anything else.

If your server has IPv6, test that path too. A provider can treat IPv4 and IPv6 differently, and Postfix will use IPv6 for some deliveries if the server has an IPv6 address and inet_protocols allows it. Our own servers send over IPv4 only, which avoids having to give the IPv6 address its own PTR and reputation.

Provider policies at a glance

As of October 2026, from each provider's documentation:

Provider Port 25 out 465 / 587 Can it be lifted?
Hetzner Cloud Blocked (25 and 465) 587 open Yes, by limit request after one month and a paid invoice; case by case
AWS EC2 Blocked to public IPs Open Yes, via AWS's request form, per Region
Azure VMs Blocked except Enterprise Agreement and MCA-E subscriptions 587 open Enterprise Dev/Test only, through Diagnose and Solve
DigitalOcean Droplets Blocked 465 and 587 also blocked No process described in the docs
Contabo VPS No official policy page found Not documented Ask support; ours was open
OVH VPS Open on ours Open n/a

The OVH and Contabo rows are our own experience, not a published policy. The rest come from the pages linked in each section below.

Hetzner: port 25 blocked on cloud servers

Hetzner's Cloud FAQ (https://docs.hetzner.com/cloud/servers/faq/) says ports 25 and 465 are blocked by default on all cloud servers. Once you have been a customer for a month and paid your first invoice, you can open a limit request in the Cloud Console to unblock them for a valid use case. Hetzner decides case by case.

Two details are worth knowing:

  • Port 587 is open without any request, so relaying through an SMTP service works on day one.
  • The unblock is per account. If you move a server to another account or project, the new owner needs the ports unblocked too.

In your request, say what you send, roughly how much, and how you handle bounces and complaints. A one-line "please open port 25" gives them nothing to approve.

DigitalOcean: SMTP blocked on Droplets

DigitalOcean's support page (https://docs.digitalocean.com/support/why-is-smtp-blocked/) says SMTP ports 25, 465 and 587 are blocked on Droplets by default, including traffic through a Reserved IP. The page describes no way to have the block removed, and recommends a third-party email service instead.

This is stricter than most providers, because it closes the usual submission ports as well. On a Droplet you have two dependable options:

  1. Send through an HTTPS email API. Port 443 is open everywhere. Our API takes a POST /emails request in the same shape as Resend's.
  2. Use a relay on a non-standard port, if your provider offers one. Some services listen on ports like 2525 for exactly this reason. We only offer SMTP on 587, so on DigitalOcean use our API instead.

AWS EC2: port 25 restricted by default

AWS's EC2 documentation (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-resource-limits.html) says that by default, EC2 allows outbound port 25 traffic only to private IPv4 addresses. Traffic to public IPv4 and IPv6 addresses is blocked. You can request removal through AWS's "Request to remove email sending limitations" form. If you run instances in more than one Region, you submit a request for each.

AWS's own recommendation is to send through Amazon SES, which takes mail over SMTP on 587 or its API and is cheap per email. If you're weighing SES against the alternatives, we cover that in Amazon SES alternatives.

Azure: port 25 blocked for most subscriptions

Microsoft's troubleshooting page (https://learn.microsoft.com/en-us/troubleshoot/azure/virtual-network/troubleshoot-outbound-smtp-connectivity) splits it by subscription type:

  • Enterprise Agreement and MCA-E: outbound port 25 isn't blocked on VMs.
  • Enterprise Dev/Test: blocked by default, but you can have it removed by running the "Cannot send email (SMTP-Port 25)" diagnostic under Diagnose and Solve on the Virtual Network resource.
  • All other types, such as Pay-As-You-Go, Free Trial and similar: blocked. Microsoft recommends an authenticated SMTP relay on port 587, which it says isn't restricted on any subscription type.

So if you're on a pay-as-you-go Azure subscription, plan on relaying.

Contabo: port 25 policy unclear

We couldn't find an official Contabo page on port 25. Forum reports conflict: some users say it was open, others that outbound port 25 was blocked until they asked support. Our own Contabo VPS, ordered in October 2026, had outbound port 25 open when it arrived. Run the netcat test, and if it times out, open a support ticket and ask.

Contabo also assigns a default reverse DNS name like vmi123456.contaboserver.net. Change it in the control panel before sending. See reverse DNS for email for why that matters.

Your options when port 25 is blocked

Option 1: Ask the provider to lift the block

This is the right choice if you really want to run your own mail server that delivers directly. Give the provider a clear use case: what you send, to whom, how much, and how you handle bounces and unsubscribes. Expect to wait, and expect some requests to be refused.

Once it's open, outbound port 25 is the start, not the finish. You still need a PTR record, SPF, DKIM, DMARC and a slow warm-up on an IP with no history. Our Postfix on Ubuntu guide covers the build and our IP warm-up guide covers the first weeks.

Option 2: Relay through an authenticated SMTP service

Keep Postfix on the VPS, but have it hand every message to an SMTP service on port 587, which delivers from its own IPs. Your apps keep using localhost:25 and nothing else changes.

# /etc/postfix/main.cf
relayhost = [smtp.ownmailserver.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = encrypt
# /etc/postfix/sasl_passwd
echo '[smtp.ownmailserver.com]:587 ownmailserver:YOUR_API_KEY' | sudo tee /etc/postfix/sasl_passwd
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
sudo systemctl reload postfix

The square brackets tell Postfix to connect to that host directly instead of looking up its MX records. The same pattern works with any relay. Swap in their hostname and credentials. Your From domain still needs to be set up with the relay (SPF, DKIM, DMARC), or the relayed mail won't align.

Option 3: Send through an email API over HTTPS

If the app is the only thing that sends mail, skip SMTP entirely. An HTTPS API on port 443 works on every provider, including DigitalOcean, and you get bounce and complaint events back without parsing mail logs.

curl -X POST https://api.ownmailserver.com/emails \
  -H "Authorization: Bearer $OMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from":"app@example.com","to":"user@example.org","subject":"Hello","text":"It works."}'

Option 4: Move the mail server to a host that allows port 25

If you want your own server, nothing forces it to live with your app. Many teams keep the app where it is and run a small mail VPS at a provider that allows port 25, with the app relaying to it on 587. That's how we run our own domains, as described in how we moved off Resend and Mailgun.

Which option to pick

Your situation Best fit
App on DigitalOcean, only transactional mail HTTPS email API
App on AWS, happy to build on AWS Amazon SES
Want your own server and IP, provider will unblock Request the unblock, then warm up
Provider won't unblock, existing Postfix setup Relay on 587
Want your own server but your host won't allow it Separate mail VPS at a host that allows port 25

If you'd rather not run any of it, our pay-as-you-go sending gives you an API and SMTP on 587 with warm-up and monitoring included. If you want your own server on a VPS you control, our managed email server service builds and looks after it.