Last updated: July 2026

In short: After this guide every one of your Mailcow domains publishes a correct SPF record — and the supporting prerequisites (PTR, IPv6) are right too.

Prerequisites

  • A running Mailcow server with a fixed MAILCOW_HOSTNAME (e.g. mail.example.com)
  • Access to your domain(s)’ DNS management
  • Access to your server provider’s PTR management

What is SPF?

SPF (Sender Policy Framework) is a TXT record in your domain’s DNS. It lists which mail servers are allowed to send email with your domain as the sender. When self-hosting you’re responsible on both sides: your Mailcow checks incoming SPF of other domains — and your own domains need clean records so Gmail, Outlook & co. accept your mail.

For context: SPF alone is not complete protection. Only together with DKIM and DMARC does it become a solid foundation — the Mailcow docs recommend all three.

The starting point at Mailcow

Mailcow itself sets no DNS records — it can’t, since your DNS zone is at your domain/DNS provider. But the Mailcow docs define precisely what they expect. The recommended SPF record:

v=spf1 mx a -all

This means only this server (your domain’s MX) may send — everything else is hard-rejected. For a self-hosted server that’s exactly right: you know your sending paths.

Important: every domain you create in Mailcow needs its own set of records — MX plus SPF, not just the main domain.

Step-by-step guide

1. Check PTR records (the underrated prerequisite)

Before SPF even helps: the PTR record of your server IP must match the MAILCOW_HOSTNAME — the Mailcow docs put this at the top of the DNS requirements. You set the PTR at the provider the IP comes from (Hetzner, Netcup, …). And: separately for IPv4 and IPv6, if your server sends over both.

dig -x 203.0.113.25 +short    # must return mail.example.com.

2. Check whether SPF is already active

dig TXT example.com +short | grep spf1

Alternatively, drop your domain into the free MXAudit scanner — it checks SPF and the PTR mapping of your MX IPs in one go.

3. Set the SPF record at your DNS provider

For each Mailcow domain, create a TXT record on the main domain (@):

v=spf1 mx a -all

mx authorizes the servers behind your MX records (i.e. your Mailcow), a additionally the IP behind the domain’s own A/AAAA record. Where exactly you enter the record depends on the DNS provider — see our guides for IONOS, Strato, All-Inkl, Netcup, and Hetzner DNS.

4. Add additional senders (if needed)

If a newsletter service also sends for the domain alongside Mailcow, its include goes into the same record:

v=spf1 mx a include:spf.newsletter-dienst.de -all

Per domain the rule holds: only one SPF record. Two TXT entries with v=spf1 cause a permerror.

5. Do DKIM at the same time

The Mailcow docs strongly recommend generating a DKIM key in the Mailcow UI and setting the corresponding TXT record in DNS. SPF authenticates the server, DKIM signs the message — together with DMARC it becomes a rounded setup.

6. Wait until the change is live

DNS changes take time: depending on TTL and caching it can take a few hours until every server worldwide sees the new record.

The components in detail

ComponentMeaning
v=spf1version identifier, always at the start
mxallows the servers behind the MX records — your Mailcow
aadditionally allows the IP behind the domain’s A/AAAA record
-allhardfail: everything else is rejected — the right choice with known sending paths

Verify the result

Check your configuration with the free MXAudit scanner — it shows SPF syntax, lookup consumption, and PTR mapping of your MX IPs at a glance.

Or directly in the terminal:

dig TXT example.com +short | grep spf1

The output must contain exactly one record with v=spf1.

Common mistakes

PTR missing or pointing elsewhere. The classic when self-hosting: SPF is right, but the reverse DNS of the server IP doesn’t match the hostname — many recipients reject on that basis alone. Fix the PTR at the IP provider.

Forgot IPv6. If your server sends over IPv6, the IPv6 address also needs a PTR — and the AAAA records must match your record. Otherwise exactly those deliveries fail at modern recipients that prefer IPv6.

Only the main domain provided for. Every domain created in Mailcow needs MX and SPF records. A forgotten second domain otherwise sends unprotected.

Two SPF records. Two TXT entries with v=spf1 cause a permerror — all sources belong in a single record.

+all at the end. A +all allows any server to send and makes the whole record useless — don’t copy it.

Forwarding fails. If a recipient auto-forwards your mail, SPF often fails at the final recipient — the forwarding server isn’t in your record. When self-hosting you can enable SRS on the forwarding side; as a sender, DKIM and DMARC catch the case.

Further reading