Email is the quietest part of an Odoo deployment and the one that fails most invisibly. Invoices go out, quotations go out, portal invitations go out, and the system reports every one of them as sent. Weeks later a customer says they never received anything, and you discover that a large share of your mail has been landing in spam folders or getting rejected outright since go-live.
The cause is almost never Odoo itself. It is the gap between what Odoo sends and what receiving mail servers are willing to trust.
Odoo does not deliver mail, your mail server does
Odoo hands each message to an outgoing SMTP server that you configure. That could be Google Workspace, Microsoft 365, a transactional provider, or your own mail host. Odoo's job ends at handing over the message. Everything that decides whether Gmail or Outlook accepts it, files it in spam, or rejects it happens after that handoff, and it is governed by DNS records on your domain.
This is the single most useful thing to understand before troubleshooting. If mail is going to spam, the fix is rarely in Odoo's settings screen. It is in your DNS zone and in your mail provider's configuration.
The three records that decide whether you land
- SPF is a TXT record listing which servers are allowed to send mail for your domain. If you send Odoo notifications through a provider that is not in your SPF record, receivers treat those messages as unauthorized. The common mistake is adding a new sending service and forgetting that SPF allows only one such record per domain, so a second one invalidates both.
- DKIM is a cryptographic signature added by your sending server, verified against a public key published in DNS. It proves the message was not altered in transit and genuinely came from an authorized sender. Most providers generate the key for you, but the record has to be published on your domain before signing does anything.
- DMARC ties the two together and tells receivers what to do when a message fails. It also asks them to send you aggregate reports. Publishing DMARC in monitoring mode first, reading the reports, and only then tightening the policy is the safe order. Going straight to a reject policy without checking which of your systems are sending mail is how companies accidentally block their own invoices.
Where most Odoo setups actually break
Authentication is checked against the domain in the message, and Odoo makes this subtle. A notification about a sales order is sent on behalf of the salesperson, so the visible from address may be a personal company mailbox, while the envelope sender used for bounce handling belongs to Odoo's catchall address. If those two domains disagree and your provider does not sign the message, DMARC alignment fails even though SPF and DKIM both technically pass.
Two practical consequences follow. First, decide deliberately which domain Odoo sends from and make sure that domain is fully authenticated. Second, do not let Odoo send as arbitrary external addresses. If a portal user's own address ends up in the from field, you are asking receivers to accept mail claiming to be from a domain you do not control, which is exactly what these records exist to stop.
Bounces and replies are part of deliverability
Odoo uses a catchall address to route replies back onto the right record, and a bounce address to catch delivery failures. If neither mailbox exists, or nothing is fetching from them, two things break at once. Replies from customers never appear in the chatter, so your team assumes silence, and hard bounces are never recorded, so Odoo keeps sending to dead addresses. Repeatedly sending to invalid recipients damages the reputation of your sending domain, which then hurts delivery of the mail that was fine.
Verify that the catchall and bounce mailboxes exist on the mail side, that the alias domain configured in Odoo matches the domain you actually send from, and that incoming mail is being collected on a schedule.
Separate transactional mail from campaigns
Invoices, order confirmations, and portal invitations are transactional. Newsletters and mass mailings are not. They have different volumes, different complaint rates, and different consequences when something goes wrong. Sending both from the same domain means one badly targeted campaign can degrade delivery of your invoices. Using a subdomain for marketing mail keeps that risk contained.
A short checklist when mail stops arriving
- Check Odoo's outgoing mail queue first. Messages stuck in the queue are a connection or credentials problem, not a deliverability problem.
- Send a test to a mailbox on a different provider and read the received headers to see the actual SPF, DKIM, and DMARC results.
- Confirm the sending domain matches the authenticated domain.
- Read the DMARC aggregate reports for sources you did not expect.
- Check whether the sending IP or domain appears on a public blocklist.
What hosting can and cannot do here
Managed hosting gives you a stable place to test this properly. On Plemo, our managed Odoo hosting platform, you get staging and sandbox environments alongside production, so mail server settings, alias domains, and template changes can be validated before they touch live customer communication, and automated backups and point-in-time recovery mean a misconfiguration is recoverable.
What hosting cannot do is publish DNS records on a domain you own. SPF, DKIM, and DMARC live with your registrar and your mail provider, and the decision about which domain your business sends from is a business decision, not an infrastructure one. Getting it right is a short piece of work that pays for itself the first time an invoice arrives in an inbox instead of a spam folder. If you want that reviewed as part of ongoing operations rather than as a one-off, it fits naturally into a managed support arrangement.
