Why VPS emails land in spam and how to fix it

You set up Postfix on your VPS, sent a test message to Gmail, and watched it drop into the Promotions tab. Or worse, straight into Spam. The first time this happens you assume the mail server is broken, but it is not. It is a reputation and authentication problem, and you can fix it with four DNS records and a realistic warmup plan. This post walks through why VPS emails land in spam and how to fix it on a self-managed server, with exact commands for Ubuntu 24.04 and Debian 12.
Prerequisites
- A Linux VPS with a Linux VPS that runs Ubuntu 24.04 or Debian 12, with root or sudo access.
- A domain name where you control the DNS zone, from a registrar or DNS provider that supports TXT records.
- Postfix (or another MTA) already installed and sending mail. If you have not configured it yet, this post assumes a working outbound setup.
- A static SMTP VPS with a dedicated IPv4, because a shared or frequently reused IP is far harder to keep clean.
Why do VPS emails land in spam in the first place?
When you send from a VPS, your mail is judged by the receiving server before the recipient ever sees it. Gmail, Outlook, and Yahoo run a three-factor test on every message. First, does the sender authenticate? That means SPF, DKIM, and DMARC must all pass. Second, does the IP address have a history of sending legitimate mail, or has it been used for bulk campaigns and abuse? Third, does the content look like spam? Most VPS owners fail the first two tests because they never set up the DNS records, and they fail the second because the IP has no reputation yet.
The painful truth is that a fresh IPv4 from any provider starts with zero reputation. Receiving servers treat unknown IPs with suspicion, not with trust. You cannot buy a good reputation, you have to build it with consistent, authenticated, low-volume sending. That is why a server with a clean IP and the right records still needs a warmup period, usually 2 to 4 weeks.
There is also a location factor. If your recipients are in Vietnam and your mail leaves a server in another country, the routing adds delay and increases the chance of being flagged. A Vietnam IPv4 reduces that friction because the mail enters the receiving network from a familiar range.
Step 1 - Verify what is failing before you change anything
Do not guess. Send a test message and check the headers. The fastest way is to send from your server to a Gmail address, then open the original message and look at the Authentication-Results header. It tells you exactly which mechanism passed and which failed.
# Send a test message from your VPS
echo "Test email body" | mail -s "Deliverability test" [email protected]
In Gmail, open the message, click the three dots, then "Show original". Look for lines like these:
Authentication-Results: mx.google.com;
spf=pass (google.com: domain of [email protected] designates 103.x.x.x as permitted sender)
[email protected];
dkim=pass [email protected] header.s=default;
dmarc=pass (p=QUARANTINE sp=QUARANTINE)
header.from=example.com
A fail or neutral value for SPF, DKIM, or DMARC tells you what to fix first. If all three pass and mail still goes to spam, the problem is IP reputation, which Step 5 covers. Use a tool like dig locally to inspect your own records:
dig TXT example.com
dig TXT default._domainkey.example.com
dig TXT _dmarc.example.com
dig -x 103.x.x.x
These four commands show SPF, DKIM, DMARC, and rDNS in seconds. The output should match the records you believe you published.
Step 2 - Publish SPF and stop spoofing your own domain
SPF (Sender Policy Framework) is a TXT record that lists which servers are allowed to send mail for your domain. Without it, receivers assume anyone can send as you, which is why so many VPS emails land in spam. A minimal SPF record for a single server looks like this:
v=spf1 ip4:103.x.x.x -all
Add it as a TXT record at the root of your domain. The ip4: mechanism pins the record to your single IPv4, and the -all at the end hard-fails anything else. If you also send from a web form plugin or a newsletter service, add their mechanisms before -all. For example, if you use Mailgun as a fallback:
v=spf1 ip4:103.x.x.x include:mailgun.org -all
Do not stack multiple include: lines you do not need. Every include expands the lookup count, and SPF silently breaks past 10 DNS lookups. Keep it tight. After publishing, wait for DNS to propagate and verify:
dig TXT example.com | grep "v=spf1"
If your mail goes through a relay or a third-party service, make sure that service appears in SPF too, otherwise your authenticated messages still fail SPF.
Step 3 - Sign every message with DKIM
DKIM is a cryptographic signature. Your server signs the message with a private key, and the receiving server verifies it against a public key published in DNS. Even if every other mechanism fails, a valid DKIM signature goes a long way toward convincing Gmail you are legitimate.
With Postfix and OpenDKIM on Ubuntu 24.04, the setup is direct. Install the package and generate a key pair:
apt update
apt install opendkim opendkim-tools
# Create the key directory and generate a 2048-bit key
mkdir -p /etc/opendkim/keys/example.com
opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s default -v
That command creates default.private and default.txt. The .txt file contains the public key you publish as a TXT record named default._domainkey.example.com. Open it and copy the entire p= value into DNS:
cat /etc/opendkim/keys/example.com/default.txt
Now configure Postfix to use the key. Edit /etc/opendkim.conf and make sure these lines are present:
Mode sv
SubDomains no
Canonicalization relaxed/simple
Socket inet:8891@localhost
SigningTable refile:/etc/opendkim/signing.table
KeyTable refile:/etc/opendkim/key.table
InternalHosts /etc/opendkim/trusted.hosts
Create the table files and add your domain:
echo "default._domainkey.example.com example.com default:/etc/opendkim/keys/example.com/default.private" > /etc/opendkim/key.table
echo "*@example.com default._domainkey.example.com" > /etc/opendkim/signing.table
echo "127.0.0.1
localhost
example.com" > /etc/opendkim/trusted.hosts
Wire Postfix to the milter and restart both services:
postconf -e "milter_protocol = 6"
postconf -e "milter_default_action = accept"
postconf -e "smtpd_milters = inet:localhost:8891"
postconf -e "non_smtpd_milters = inet:localhost:8891"
systemctl restart opendkim postfix
Verify the signature appears in your outbound mail:
grep -i dkim /var/log/mail.log | tail -5
A line like dkim=pass means Postfix is signing correctly. If you would rather not run OpenDKIM yourself, some SMTP VPS plans with clean IPs handle DKIM key management in the control panel, which saves a few steps.
Step 4 - Enforce policy with DMARC
DMARC tells receivers what to do with mail that fails both SPF and DKIM. It also gets you a reporting loop so you can see who is sending as you. Without DMARC, receivers apply their own judgment, and a suspicious IP with no policy is more likely to be dumped in spam.
Publish a DMARC TXT record at _dmarc.example.com. Start with a monitoring policy so you do not break anything, then tighten it:
v=DMARC1; p=none; rua=mailto:[email protected]; fo=1; adkim=s; aspf=s
The p=none value tells receivers to monitor but not reject. Run this for a week, check the aggregate reports, then switch to p=quarantine, which sends failing mail to spam instead of the inbox:
v=DMARC1; p=quarantine; rua=mailto:[email protected]; fo=1; adkim=s; aspf=s
Only move to p=reject once you are certain all legitimate mail authenticates, usually after several weeks of clean reports. Verify your record:
dig TXT _dmarc.example.com
DMARC also requires alignment. The domain in the From header must match the domain in SPF or DKIM. If you send from [email protected] but sign with a key for another domain, DMARC fails even when DKIM passes.
Step 5 - Set rDNS (PTR) so the IP matches your domain
Reverse DNS is the record that maps your IPv4 back to a hostname. Gmail and Outlook check it on every connection. If the PTR hostname does not match the HELO name your server announces, or if it points to a generic provider hostname, your mail scores poorly.
On most providers you set the rDNS from the control panel. At thueVPS, you open the VPS management page, find the network or DNS settings, and set the PTR record for your dedicated IPv4 to something like mail.example.com. This is a per-IP setting, so you set it once and it applies to all mail from that address.
Then configure Postfix to announce that same hostname during the SMTP handshake:
postconf -e "myhostname = mail.example.com"
postconf -e "smtp_helo_name = mail.example.com"
postconf -e "myorigin = example.com"
systemctl restart postfix
Verify the rDNS resolves back to your server:
dig -x 103.x.x.x
The output should contain mail.example.com. Also make sure an A record for mail.example.com points to your IPv4, otherwise the forward and reverse records do not match, which is called a forward-confirmed reverse DNS (FCrDNS) failure. This matters more than most people think; a mismatch here is one of the most common reasons VPS emails land in spam even with valid SPF and DKIM.
Step 6 - Warm up the IP and keep volume realistic
Authentication is only half the fight. A brand new IPv4 has no reputation, and no DNS record fixes that. The fix is a warmup schedule: start with a low daily volume and increase it gradually so receiving servers learn your IP sends legitimate mail.
A realistic 30-day schedule for a transactional server looks like this:
| Days | Daily volume | Recipients |
|---|---|---|
| 1 to 5 | 20 to 50 | Only engaged users who clicked recently |
| 6 to 12 | 100 to 200 | Plus active subscribers |
| 13 to 20 | 300 to 500 | Add the full opted-in list |
| 21 to 30 | 500 to 1000 | Monitor bounces and spam complaints daily |
Never blast a cold list on day one. If you send 10,000 messages from an IP with no history, you will hit spam filters immediately and burn the IP. Space the sends out, keep the content identical to what real users expect, and watch the complaint rate. Anything above 0.1% complaints is a red flag, and above 0.3% you risk blacklisting.
Also watch your bounce rate. A 2% to 5% bounce rate is normal during warmup, but double-digit bounces mean your list has stale addresses and receivers will start flagging you. Clean the list before you scale up.
Step 7 - Check blacklists and monitor your sender reputation
Even with everything configured, your IP can end up on a blocklist if a previous owner abused it or if a spam trap catches an old address on your list. Check the major blacklists after warmup and then weekly:
# Check common blocklists with dig
dig +short 2.0.0.127.zen.spamhaus.org
dig +short 103.x.x.x.zen.spamhaus.org
# If it returns 127.0.0.2 or similar, you are listed
An empty response means you are not on that list. For a broader check, use a web tool like MXToolbox, but the dig command is enough for a quick verification in the terminal. If your IP shows up on a list, you do not start over. You request delisting, fix the cause, and keep sending low volume until the listing clears.
Keep an eye on your sending history too. If you run bulk sending that outgrows a shared relay, moving to a dedicated sender with a clean IP becomes the right call, and the warmup schedule above applies exactly the same way.
Frequently asked questions
Why is my VPS email going to spam even with SPF and DKIM set up?
Authentication records are only part of the equation. The IP address itself has no reputation yet, or the rDNS record does not match the hostname your server announces. Check the Authentication-Results header first, then verify the PTR record resolves to the same hostname used in the HELO command. A mismatch there is a common reason authenticated mail still lands in spam.
How long does it take to fix email deliverability on a new VPS?
DNS records propagate within hours, but IP reputation takes 2 to 4 weeks of consistent, low-volume sending. You can speed up the process by warming up gradually, keeping bounce rates under 5%, and avoiding sending to stale or purchased lists. There is no way to skip the reputation-building period.
Do I need a dedicated IPv4 for reliable email sending?
Yes, if you plan to send regular mail. A dedicated IPv4 gives you full control over the rDNS record and a reputation you build yourself. Shared IPs inherit the behavior of other senders, which can hurt deliverability. That is why a SMTP VPS with a clean dedicated IP is a standard choice for production mail servers.
What is a good DMARC policy to start with?
Start with p=none and a monitoring address so you can see which senders fail authentication. After a week of clean reports, switch to p=quarantine to send failures to spam. Only escalate to p=reject after several weeks without issues. Moving straight to reject can silently break mail you did not know about.
Can I send bulk newsletters from a regular VPS?
Yes up to a point, but a standard VPS is not built for high-volume blasting. Bulk sending needs a proper warmup, a clean IP, and strict list hygiene. If you want to send large campaigns, consider a dedicated SMTP setup or a transactional relay, and keep your VPS for operational mail like invoices and notifications.
Related articles
- Configure SPF, DKIM, and DMARC on a mail VPS
- Set up rDNS on an SMTP VPS in 2026
- Warming up a new sending IP, a realistic 30 day schedule
- SPF, DKIM, and DMARC on a self hosted SMTP server
越南 VPS 的干净 IPv4 配合 SPF、DKIM 和 rDNS,是邮件不进垃圾箱的基础。
A clean Vietnam IPv4 on your VPS, combined with SPF, DKIM, and rDNS, is the foundation for keeping mail out of spam.
VPS 邮件进垃圾箱的修复要点
本文解释了 VPS 邮件进入垃圾箱的主要原因:缺少 SPF、DKIM、DMARC 三个 DNS 记录,rDNS 不匹配,以及全新 IP 没有发信信誉。修复方法是先检查邮件头确认哪个环节失败,然后依次发布这些记录,设置 PTR,并按照 30 天计划逐步提高发信量。越南本地的 IPv4 可以降低路由延迟和进入垃圾箱的概率。任何 VPS 都无法跳过信誉积累期,必须从低量开始温和提升。


