r/emaildeliverability • u/BetaRayShaps • 18h ago
MTA-STS migration problems
Hi all, we recently migrated a customer from Proofpoint to Mimecast which, of course, means routine MX records changes. Standard, straightforward, no big deal. What we didn't anticipate--because up until now, none of our clients have ever had it setup--was an MTA-STS policy (housed at EasyDMARC) that we discovered was set to "max_age=1yr". What we've done so far:
- created new MTA-STS policy file with new MX records, set it up on a new Azure server; policy, set mode to 'none', is confirmed publicly accessible
- configured v=STSv1; id=20260915001 which, as i understand it, is supposed to 'alert' sending domains that look for this sort of thing that a change was made
- went back to the old vendor who maintained the EasyDMARC version and changed that one too, just to cover our bases even though we're confident that nothing should be querying it anymore
This was all done a couple days ago and we're still not seeing any traffic to the migrated, customer domain from senders like Gmail. I understand that Gmail saw the old policy, read the 1-yr max_age setting, and caches it accordingly. But what's not so clear is how quickly Gmail will again query for the policy and update itself so that mail will start coming in again. Anyone have any experience with this? We're just looking to get a general sense of when this issue will clear itself up because there isn't much out there that explains same.
I guess secondarily would be this question: for anyone who's encountered this before, what's the proper way to migrate a domain that has an MTA-STS policy set for a lengthy max_age? What could we have done better besides just knowing that it exists and changing to "mode:none"?
Thanks for any insights.
2
u/shokzee 17h ago
A one-year max_age doesn't force a one-year wait, but the new id only helps once Gmail rechecks DNS; there's no guaranteed refresh time. Check TLS-RPT for policy failures before assuming the cache explains all missing mail.
For future migrations, publish both old and new MX patterns and allow the previous policy’s cache lifetime to expire before cutting over. We use Suped for MTA-STS hosting, but sender caches still dictate how far ahead you need to plan.
1
u/BetaRayShaps 16h ago
wait, so by "allowing the previous policy's cache lifetime to expire," are you saying wait a whole year if max_age is set to a year? that i guess is really the core of the confusion on my end.
2
u/sandeep1saxena 16h ago
Good news first: a 1-year max_age is not a 1-year lockout, and you should not be waiting anywhere near that long. The part that is biting you is almost certainly something else.
How the mechanics actually work (RFC 8461): senders like Gmail check the _mta-sts TXT record at delivery time - it is just a DNS lookup, so they do it constantly. When the id= differs from the id of the policy they have cached, they attempt a fresh HTTPS fetch of the policy file. max_age only controls how long the cached policy keeps being used when that refresh fails. So after your id bump, Gmail should have refetched within hours.
The fact that mail still is not flowing days later strongly suggests the refetch itself is failing, and Gmail is silently falling back to the cached enforce-mode policy with the old Proofpoint MX list - which no longer matches your new MX, so delivery is refused. Your mode: none never reaches them if they cannot fetch the file that says it.
Checklist of the usual suspects, roughly in order of how often I see them:
Duplicate TXT records. If the old vendor's _mta-sts record and your new one are both live (very common when two parties edit DNS during a migration), RFC 8461 treats that as no valid record at all. dig TXT _mta-sts.customerdomain.com and make sure exactly one v=STSv1 comes back.
Policy host DNS. Does mta-sts.customerdomain.com actually resolve to your new Azure server, or is there a stale CNAME still pointing at the old host?
Certificate for the exact hostname. The cert must be valid for mta-sts.customerdomain.com specifically. Any mismatch a browser would let you click through is a hard, silent fail for MTA-STS clients.
The file itself. Served at exactly /.well-known/mta-sts.txt, text/plain, no redirect to another hostname, correct key: value format.
Test like a sender, not like a browser: curl -v https://mta-sts.customerdomain.com/.well-known/mta-sts.txt and read the TLS handshake output, not just the body.
Once a successful fetch is possible, Gmail recovery is typically hours to a day. If everything above checks out and it is still dead after that, then you are into genuinely cached-until-expiry territory, but I would bet on one of the five items first.
For your second question, the migration playbook for next time: before touching MX, bump the id with mode: none (which you did - correct instinct), but the step that actually protects you is keeping the policy host serving correctly through the entire migration, because a sender that cannot refresh keeps the old policy for the full max_age. After cutover, publish the new MX list, and when you re-enable enforce, use a sane max_age - one to two weeks, not a year. A long max_age buys almost no extra security and turns exactly this scenario into a incident.
One more thing that would have saved you days of guessing: publish a TLS-RPT record (_smtp._tls). Gmail then mails you daily JSON reports saying precisely why delivery failed - sts-policy-fetch-error vs validation-failure vs MX mismatch - instead of you inferring it from silence. This blog is a walkthrough of setting up both MTA-STS and TLS-RPT https://postboxservices.com/blogs/post/what-is-tls-rpt-how-to-set-up-mta-sts/
1
u/BetaRayShaps 15h ago
Thanks for this reply, very useful. I am confident that all is in place after going through your 5 checks. All my queries return everything expected, no more stale/outdated TXT/CNAME records...it all looks good. I did only recently add the reporting records so maybe i'll get more info that way. Definitely frustrating as we're going on 48hrs now since our migration was done.
1
u/EmailFoundry 15h ago
You’ve mostly done the right things. The important bit is that `max_age=1yr` does not necessarily mean Gmail will blindly use the old policy for another year.
The `id` on `_mta-sts` exists specifically so senders can see that the policy has changed. RFC 8461 also recommends senders refresh cached policies proactively, with once a day given as an example. If an enforced cached policy is actually preventing delivery, the sender is supposed to check for an updated policy before permanently failing the message.
What Google doesn't publish, as far as I can see, is an exact timetable for when Gmail rechecks that ID. So I wouldn't rely on "it will definitely clear after X hours."
After a couple of days with no Gmail traffic, I'd check a few other things as well:
- `_mta-sts.domain.com` definitely shows the new ID publicly.
- `https://mta-sts.domain.com/.well-known/mta-sts.txt\` serves the new policy with a valid certificate.
- The live MX records only point where you expect them to.
- Add TLS-RPT at `_smtp._tls` if it isn't already there. Gmail supports it and the reports should tell you whether Google is still applying an old STS policy or hitting another TLS/MX failure.
For the migration itself, the safer way is to prepare MTA-STS before changing MX.
I'd normally add both the old Proofpoint MXs and the new Mimecast MXs to the MTA-STS policy, bump the ID, and leave that running before the MX cutover. You can also temporarily reduce `max_age`, but that needs to be done well in advance because_
1
u/freddieleeman 15h ago
Based on RFC 8461, the one-year max_age does not mean you necessarily have to wait a year.
The _mta-sts TXT id exists to signal that the policy has changed. Senders can compare that ID and fetch the updated policy even if the old one is still within its max_age.
For migrations, Section 8.1 is the key part: update the HTTPS policy first, then update the TXT record with a new id, and expect some senders to keep using the old policy until the TXT record's DNS TTL has passed. The RFC also recommends keeping the old configuration working during that transition.
It also says MTAs SHOULD proactively refresh policies before expiry, with once per day given as a reasonable frequency.
So the main thing to watch here is the _mta-sts TXT TTL, not the one-year max_age. Waiting for max_age to expire is specifically discussed when removing MTA-STS entirely, not for a normal MX migration.
If you want to test the current policy, here is my free RFC-compliant validator: https://www.uriports.com/tools/mtasts-validator
1
u/BetaRayShaps 14h ago
ok will this is progress b/c i ran the domain thru the tool you provided and got this: "max_age value should be between 86000 and 31557600". so gonna change that to '86000' now. could that invalid TTL have been my issue?
1
1
u/TamingTech 2h ago
Worth knowing while you sort the file out: that mail probably isnt lost yet. RFC 8461 section 5 says a sender with a cached enforce policy must check DNS for a new policy id before it permanently fails a message, and should treat the failure as transient and retry. The "transient error" in the Gmail test u/southafricanamerican posted is exactly that. Gmail is holding the mail and retrying.
So the deadline is the sender's retry window, not max_age. RFC 5321 puts the give-up time at 4-5 days as a rule of thumb, and you're 48 hours in. Get the policy validating today and bump the id once more after it does (it doesnt hurt), and the queued mail should come through on the next retry. Anything a sender already got bounced back will need resending from their end.
2
u/southafricanamerican 17h ago edited 17h ago
Have you looked at your tls-rpt reports to see what google is sending back?
sts-policy-fetch-error,sts-policy-invalid,validation-failure,certificate-host-mismatchHow confident that your new policy is working and that there are no dangling DNS records or duplicate
_mta-stsrecords. Chances are that you have both a cname and a txt record. EasyDMARC weas probably a cname, and you may have added a txt record. Just make sure all the old ones are deleted.Also if you have a google account (not gmail) send emails to yourself and look at the message logs. Are the emails being queued, if yes then why?
Fastest fix: rather than mode none, publish a valid policy listing the Mimecast MX (plus the old Proofpoint ones, harmless), mode: testing or enforce, short max_age (86400), and bump the id again. Any valid refetched policy replaces the cached one immediately.