MTA-STS policy caching is not ordinary browser caching. The policy's max_age governs its lifetime from the last successful fetch. The discovery TXT has its own DNS TTL. Those clocks can differ substantially and explain why two senders apply different policy versions at the same time.
Record the policy that a sender could still hold
References: RFC 8461 §3.2, RFC 8461 §3.3.
Keep each published policy body, discovery id, publication time and max_age. A current endpoint screenshot cannot tell you what a sender fetched yesterday. During an incident, ask for the applied policy and fetch time from sender logs where available instead of assuming the newest body is universal.
RFC 8461 says senders should cache a policy for up to max_age and should proactively refresh before expiration, suggesting a daily refresh. These recommendations are not a guarantee of synchronized updates. Implementations may check for updates at different times, and a sender can continue applying a valid cached policy when live discovery or fetching fails.
Separate the two expiry calculations
References: RFC 8461 §3.2, RFC 8461 §5.1.
In a labelled arithmetic fixture, a policy fetched at epoch time 1000000 with max_age 86400 has an expiry boundary of 1086400. A DNS TTL of 300 does not change that calculation. If the operator publishes a new body with max_age 3600, the already cached old body does not acquire the new lifetime retroactively.
The new bounded offline fixture calculates that boundary. The retained historical transport-lab record additionally documents a deep copy of the old cache, a shorter-lived policy fetch and an assertion that the old snapshot and its expiry remain unchanged until explicit replacement. The cache portion is an explicit state/arithmetic model, not a real MTA, DNS cache or refresh scheduler; the separately retained loopback DNS/HTTPS exchanges do not broaden that cache claim. To extend the test, configure a controlled sender with an inspectable policy cache and preserve its actual fetch, refresh and delivery logs.
Update in the safe order
References: RFC 8461 §8.1, RFC 8461 §8.2.
Publish the new HTTPS body, verify it, then change the DNS id. RFC 8461 advises keeping old policies compatible with delivery while both endpoints update and the TXT TTL passes. For planned routing changes, also allow for senders that retain the old policy until its lifetime ends or a successful refresh occurs.
Keep protocol policy caching distinct from a CDN's origin cache. Senders must not use HTTP caching for policy retrieval. RFC 8461 §8.2 nevertheless permits origin-side reverse-proxy caching; verify its freshness and publication behavior rather than treating every proxy cache as prohibited. Verify the actual body from the public endpoint and ensure the hosting publication workflow exposes the intended revision.
Diagnose a delayed change without guessing
References: RFC 8461 §3.3.
Compare DNS answers, HTTPS response bytes, cached policy metadata and the sender's failure logs. A new id with an old body suggests publication ordering or hosting freshness trouble. An old id in a recursive answer may reflect DNS cache state. An old but valid cached policy during a fetch outage can be expected protocol behavior.
Do not declare every delay to be propagation. Identify which cache or dependency holds the old state, repair that component and retain a compliant receiving path throughout the transition. No live sender-cache experiment was executed for this article.
Retained historical evidence and remaining scope
The following describes preserved 7 November 2026 observations, not a network experiment rerun for this review. Newly executed offline checks are recorded separately.
The captured logical cache fixture preserves A1 fetched at 1000000 with expiry 1086400. The lab publishes B2, announces B2 through an actual UDP DNS answer and fetches B2 over HTTPS with max_age 3600. It then asserts that a deep-copied A1 snapshot still equals its original contents and retains expiry 1086400. A separate last-served ledger computes the maximum possible A1 expiry as 1000300 + 86400 = 1086700, later than B2 at 1000600 + 3600 = 1004200 and C3 at 1000900 + 3600 = 1004500. The expiry values are emitted calculations using explicit logical times; the cache-preservation comparison is an executed assertion. Neither is an emulation of an MTA refresh scheduler. An actual sender’s choice to refresh, retry or retain state remains an implementation test.