Mailcow Outbound Mail Fails When It Uses the Wrong Public IP

Mailcow was sending from the public IP of the machine where it was installed. That was the wrong address for this domain: the SPF record expected mail to leave through a different machine.
The server could send mail, so the problem did not first look like networking. The important detail appeared on the receiving side. The message was evaluated against the public IP that actually delivered it, not the public IP that the domain owner expected it to use.
Why SPF failed
SPF is checked against the sending IP visible to the recipient. It does not matter that another machine has the intended IP, or that its address is already present in the SPF record, if the Mailcow host sends directly from somewhere else.
In this case, the Mailcow machine had its own public route. Outbound mail therefore left with that machine’s address. The domain’s SPF policy did not authorize it, so recipients could reject the message or treat it as suspicious.
This is easy to miss in a multi-server setup. The mail service and the public IP named in DNS can both be under the same control, while still being different network egress points.
Route outbound traffic through the expected machine
The fix was to use WireGuard with full-tunnel routing. With the tunnel in full-tunnel mode, outbound traffic from the Mailcow host leaves through the machine whose public IP is already authorized by SPF.
The key word is full. A tunnel that only routes private subnets will not change the public source address used for normal outbound connections. Full-tunnel routing sends that traffic through the designated egress machine instead.
Verify the change before relying on it
After changing the route, send a real test message to a mailbox where you can inspect the authentication result. Check these points:
- The recipient should see the expected sending public IP.
- SPF should pass for the envelope sender’s domain.
- The route should remain correct after reconnecting WireGuard or restarting the Mailcow host.
It is also worth checking that DNS, reverse DNS, DKIM, and DMARC still agree with the same sending identity. Full-tunnel routing solves the source-IP mismatch; it does not replace the other parts of normal mail authentication.
The operational lesson
Do not assume the public IP in your SPF record is the one Mailcow is using. Verify the egress address from an actual sent message. When the service lives on one machine but the authorized public identity belongs to another, routing is part of the email configuration.
For this topology, WireGuard full tunnel made the intended network path explicit and brought the observed sender IP back in line with SPF.