554 5.7.5 Permanent Error Evaluating DMARC Policy: How to Diagnose and Fix It
This bounce means the receiving server checked your DMARC policy, your message failed, and your own record told it to reject. Here's how to find which leg failed and repair it.
A message bounced and the body of the bounce contains this:
554 5.7.5 Permanent error evaluating DMARC policy
Read it carefully, because the wording is misleading. Nothing malfunctioned. The receiving mail server looked up your domain's DMARC record, evaluated your message against it, found the message failed authentication, and then did exactly what your record instructed it to do. "Permanent error" describes the outcome for the message, not a fault in the system.
You published a policy of p=reject or p=quarantine, and something you sent didn't pass. The receiver honored you. Most commonly this bounce comes back from Yahoo and AOL, though the underlying cause is identical whichever provider emits it.
The 5.7.5 and the 554 both mean permanent, so retrying changes nothing. Whatever sent that message will keep failing until you fix the authentication.
Start by confirming what your policy says
dig +short TXT _dmarc.yourdomain.com
Windows:
nslookup -type=TXT _dmarc.yourdomain.com
If you see p=reject, that's the instruction the receiver followed. Fine. The policy isn't the problem, and rolling it back to p=none to stop the bounces is treating the smoke alarm rather than the fire. It also reopens your domain to spoofing.
The real question is which message failed and why.
Three things it's almost always going to be
A sender you forgot about. Something sends as your domain that you never authenticated. An invoicing tool, a booking system, a form plugin, a CRM that a contractor connected. Whatever it is, it's sending as you@yourdomain.com without a DKIM signature that aligns and without being in your SPF record. When you moved to p=reject, that sender started bouncing and nobody connected the two events.
Alignment, not authentication. This one is subtle and it's the most common real cause. Your SPF check passes. Your DKIM signature validates. DMARC still fails, because passing isn't sufficient on its own.
DMARC requires that SPF or DKIM pass and that the passing domain match the domain in the visible From: header. SPF authenticates the Return-Path, which for most sending platforms is their bounce domain, not yours. So SPF genuinely passes, on their domain, and DMARC compares it to yours, finds a mismatch, and counts SPF as unaligned. Same story with DKIM if the signature's d= value is the platform's domain rather than yours.
If a service offers custom DKIM signing, sometimes called branded DKIM or authenticated sending domain, turn it on. That makes d= equal your domain, DKIM aligns, and DMARC passes no matter what the Return-Path says.
Forwarding. A recipient auto-forwards your mail to another address. Forwarding rewrites the path and breaks SPF, and if the forwarder modifies the message at all, the DKIM signature breaks too. Now nothing passes, DMARC fails, and your p=reject policy gets applied to a message you legitimately sent to a legitimate recipient.
Mailing lists cause the same problem for the same reason. There's a mitigation called ARC that lets a forwarder vouch for the original authentication result, but you can't control whether the receiving side honors it. Mostly you accept some forwarding loss as the cost of enforcing a policy.
Reading the actual failure
Guessing is slow. Get the real answer from the headers of a message that failed, or from a copy sent to an address you control.
In Gmail, open the message, hit the three-dot menu, and choose Show original. You want the Authentication-Results header, which reads something like:
Authentication-Results: mx.google.com;
dkim=pass header.i=@yourdomain.com;
spf=pass (google.com: domain of bounce@sendingplatform.com
designates 1.2.3.4 as permitted sender)
smtp.mailfrom=bounce@sendingplatform.com;
dmarc=fail (p=REJECT sp=REJECT dis=NONE) header.from=yourdomain.com
Look at that example closely, because it's the classic shape of the problem. DKIM passed. SPF passed. DMARC failed anyway. The smtp.mailfrom is sendingplatform.com while header.from is yourdomain.com, so SPF is unaligned, and whatever DKIM signed with clearly wasn't aligned either. Two green checks and a red one.
If dkim=pass shows header.i=@yourdomain.com, DKIM is aligned and DMARC should pass. If it shows the platform's domain instead, that's your fix: enable custom DKIM signing on that platform.
The faster route: aggregate reports
If your DMARC record includes a rua= tag, receivers are already mailing you daily XML reports naming every source that sent as your domain and whether each one passed. That's the inventory you need, and it arrives without you doing anything.
No rua= tag? Add one now.
v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.com; fo=1
The fo=1 asks receivers to send a failure report when any authentication mechanism fails, which is useful while you're actively debugging. The XML is unpleasant to read by hand, so run it through a parser; several will ingest reports free at low volume.
Give it a few days. The reports will name the tool that's been bouncing.
Fixing it, in order
Once you know which sender is failing, the repair is mechanical.
Add the sender to SPF if it isn't there, keeping in mind SPF permits a maximum of ten DNS lookups; exceed it and the record hits a permanent error and every check fails. Each include: you add counts, and some includes nest their own. If you're near the limit, drop senders you no longer use rather than flattening the record, since flattening breaks quietly whenever the provider changes IPs.
Then set up DKIM for that sender, and specifically set up aligned DKIM. Publish the CNAME or TXT records the platform gives you, verify inside their dashboard, then send a test to an address you can inspect and confirm header.i= shows your domain.
Send that test to a Yahoo address if Yahoo is where the bounces came from. Testing against Gmail alone gives you a partial answer.
When to temporarily relax the policy
If mail your business depends on is bouncing right now and you need hours rather than days, moving from p=reject to p=quarantine is defensible. Failing messages go to spam instead of being refused, so they're at least recoverable, and you buy time to fix the real problem.
Going back to p=none should be a last resort, and if you do it, set a calendar reminder to return. Domains sit at p=none for years because someone disabled enforcement during an incident and the follow-up never got scheduled, which is exactly the state that gets you a DMARC quarantine/reject policy not enabled warning the next time anyone scans you.
What you shouldn't do is leave the policy relaxed and call the bounce fixed. The bounce was your own instruction being carried out correctly. Removing the instruction removes the symptom and hands your domain back to whoever wants to spoof it.
The uncomfortable version of this
Sometimes the investigation ends somewhere annoying: a vendor that can't do aligned DKIM, or an internal system nobody wants to touch. At that point you're choosing between enforcing DMARC and keeping that sender working.
Subdomains are the usual escape hatch. Move the awkward sender to notifications.yourdomain.com, give that subdomain its own DMARC record with a softer policy, and keep the root domain at p=reject. Your organizational domain stays protected, and the vendor keeps sending. Do specify a policy on the subdomain explicitly, because a subdomain with no record of its own inherits the parent's policy through the sp= tag, which defaults to whatever p= says.
That's usually the pragmatic ending. Not elegant, but it stops the bounces without giving up the protection you set the policy for in the first place.
Try Flomailr free
Ready to put this into practice?
Flomailr is built for small businesses, visual email builder, automation flows, and real analytics. Free up to 500 contacts, no credit card required.
Start free today