SPF, DKIM and DMARC: why your mails arrive or end up in spam

What the three records do, how to check them and why mails sent from the ERP need the same rules as your mailbox.

6 min read ERP rollout and operations

Your sales team sends a quote from Odoo, and the customer doesn't respond. Two days later, they ask about it: they never received anything. The email ended up in the spam folder or was silently discarded by the recipient's server. That means follow-up questions, delayed orders, and lost time, because nobody knows where the email went. Most of the time, the cause isn't the content but three DNS records of your domain: SPF, DKIM, and DMARC. (DNS is the naming system where your domain's settings are stored.)

What the Receiving Server Checks

A mail server receives a message with the sender address `vertrieb@ihre-firma.de`. It can't tell whether the message really comes from you, because sender addresses can be forged. So it asks your domain for three things:

  • SPF (Sender Policy Framework): A record lists which servers are allowed to send email for your domain. The recipient compares the address of the delivering server against it.
  • DKIM (DomainKeys Identified Mail): Your mail server signs every outgoing message with a private key. The matching public key is stored in your DNS. The recipient uses it to verify that the email came from your server and wasn't altered in transit.
  • DMARC (Domain-based Message Authentication, Reporting and Conformance): The rule that tells the recipient what to do if SPF or DKIM doesn't match the sender domain: let the message through, put it in spam, or reject it. DMARC also specifies where reports about these checks are sent.

If one of them is missing or doesn't match the actual sending path, the recipient classifies your email as suspicious.

Check question: Do you know which systems send email on your behalf? Without that list, you can't maintain SPF properly.

Where Emails Originate in Your Business

Problems rarely arise with the office mailbox, but with the systems that send in addition to it. Go through your own situations:

  • Odoo itself: Quotes, invoices, and chatter messages go out via the outgoing mail server configured in Odoo. If Odoo uses a different server than your office via SMTP (the protocol for sending email), that server must be listed in SPF and must sign with DKIM.
  • Shop integration: Order confirmations often come from the shop (Shopify, Shopware, WooCommerce) rather than from Odoo. The shop sends with your sender domain, but it is another sender that SPF and DKIM need to know about.
  • AI automation: If an agent answers customer inquiries or sends drafts, the email goes out through a mail server. Clarify which one it is and whether it signs.
  • Version upgrade and migration: After an upgrade or a server move, the IP address and mail configuration often change. The SPF record then still names the old server, and suddenly checks fail.
  • Solar PV business: If quotes, project updates, and invoices come from one system, the same applies as above. Every sending path needs a record.

Decision rule: If a system sends with your domain as the sender and is neither listed in SPF nor DKIM-signed, the recipient treats its emails as unauthenticated.

Reading the Records

All three are TXT records in DNS. You can view them with your DNS provider or retrieve them with a lookup tool such as `nslookup` or `dig`.

SPF sits on the domain itself and begins with `v=spf1`. It is followed by the permitted servers and, at the end, a rule:

`v=spf1 include:mailanbieter.example ip4:Server-IP ~all`

  • `include:` adopts the servers of your mail provider.
  • `ip4:` permits a fixed address, such as your own server.
  • `~all` means "soft fail," `-all` means "reject."

There may be only one SPF record per domain. Two records make SPF invalid. In addition, only a limited number of DNS lookups are allowed per check; too many `include:` entries lead to an error.

DKIM is stored under a name following the pattern `selector._domainkey.ihre-firma.de`. Your mail system determines the selector. The record contains the public key (`p=...`). Each system that signs usually has its own selector.

DMARC is stored at `_dmarc.ihre-firma.de`:

`v=DMARC1; p=none; rua=mailto:dmarc@ihre-firma.de`

  • `p=none` only monitors, `p=quarantine` sends to spam, `p=reject` rejects.
  • `rua=` is the address for the aggregate reports.

DMARC passes if SPF or DKIM passes and the checked domain matches the visible sender domain (alignment). So a server can pass SPF and DMARC can still fail, because it sends under its own domain instead of yours.

How to Proceed Without Losing Emails

The most common mishap: someone sets DMARC straight to `reject`, and legitimate emails are then rejected because a forgotten sending path doesn't sign. Proceed in this order:

  1. Create an inventory: all systems that send with your domain (office email, Odoo, shop, newsletter, ticketing system, agents).
  2. Add all these senders to SPF, as a single record.
  3. Set up DKIM for each system and verify it with a test email.
  4. Publish DMARC with `p=none` and a reporting address.
  5. Evaluate the reports over a few weeks. They show which servers send on your behalf and why the check fails.
  6. Only when all legitimate sources pass, switch to `quarantine` and later to `reject`.

Reading a Test Email

Send an email from Odoo to an external mailbox, for example at a large provider. Open the message source there and look for the `Authentication-Results` header. It shows `spf=pass`, `dkim=pass`, and `dmarc=pass`, or the respective failure.

  • `spf=fail` or `softfail`: The sending server is missing from SPF.
  • `dkim=none`: The system doesn't sign, or the key is missing from DNS.
  • `dkim=fail`: The key in DNS doesn't match the signature, or the message was altered in transit.
  • `dmarc=fail` with SPF passing: The domains don't match. Check which sender domain the system uses.

Repeat the test for every sending path, not just for the office mailbox.

Check Again After Changes

SPF, DKIM, and DMARC go stale silently. Check again after these events:

  • Odoo moves to a different server or is upgraded to a new version.
  • A shop or a new tool starts sending on your behalf.
  • A mail provider changes or alters its keys.

If the sending path changes, the DNS record belongs on the change list, just like access credentials and backups.

Your Next Step

Today, send a test email from Odoo to an external mailbox and read the `Authentication-Results` header there. Note pass or fail for each of SPF, DKIM, and DMARC. Then ask your DNS provider or look in the zone: Is there exactly one SPF record, and does a DMARC record exist? If both answers are yes, list all the systems that send on your behalf next.

All knowledge articles