An expired promotion doesn't expire by itself: the ended sale still on the shop, the promotion asset still serving a 404
Four country shops still displayed a twenty-euro saving three weeks after the sale ended \u2014 while the cart charged full price. In the same week, promotion assets with no end date were still pointing at a removed landing page. A promotion is a set of artefacts, not a date.
The homepage said the price had come down by twenty euros. The strikethrough was there, the old price above it, the "you save €20" line underneath. I put the product in the cart and the cart charged the old price.
Not a rounding difference. The full twenty euros, on the country shops of a home and living brand I look after, on four of them at once, three weeks after the promotion had ended.
The countdown timer had disappeared on schedule, because the countdown was the only part of the promotion that knew its own end date. Everything else — the strikethrough, the old price, the savings line — was static markup somebody had written by hand, and static markup does not stop being true on a date. It just stays there.
The same week, in the ads account
While I was working that out, a policy email arrived about a different account: four violations, destination not working. Six of the flagged assets turned out to be genuinely live and linked; roughly forty others were legacy leftovers nobody had attached to a campaign in years, which is its own lesson about reading policy notifications — separate the linked from the abandoned before you act, or you will spend a morning fixing dead things.
Three of the six were promotion assets for a World Cup offer. The offer was long over. The page it pointed at had been taken down. The assets had never been given an end date, so they were still serving, still pointing at a URL that returned a 404, and — this is the part that made me sit back — they were the root cause of a "limited by policy" flag that had been sitting on one of the campaigns for weeks. Nobody had connected the flag to the promo. It had become background noise on the account.
Nassim Nicholas Taleb, in Skin in the Game: "Bureaucracy is a construction by which a person is conveniently separated from the consequences of his or her actions." You don't need a bureaucracy for that. Four shops, an ads account and a CMS will do it. Whoever set the price banner never opens the cart. Whoever wrote the promotion asset never sees the 404.
A promotion is not a date, it is a set of artefacts
This is the thing I keep relearning. When someone says "the sale ends on the 31st", what they mean is that one price rule expires on the 31st. The promotion itself is spread across a homepage banner, a strikethrough on every product card, a category header, a countdown component, a product feed, a set of promotion assets in the ads account, an offer landing page, a handful of ad copy variants and probably an email footer.
Exactly one of those things knows the date. The rest end when a human ends them, and if nobody owns that list, the promotion doesn't end — it decays, unevenly, leaving the most visible parts standing longest.
So the fix isn't vigilance. It is making the end date structural in each system that can hold one. Google's own documentation on promotion assets has a start and end date field sitting right there, and the reason it exists is precisely this failure. Use it every single time, even for an evergreen offer, even when you are certain you will remember. You will not remember. Set it to the date you think the offer ends and extend it later; that is a two-minute job, and the alternative is an asset advertising a dead page into next year.
The exposure is bigger than a tidy-up
Displayed price not matching charged price is not a cosmetic bug. It sits in three separate places at once.
It is an ad policy problem: destination requirements mean the page a click lands on has to work and has to deliver what the ad promised, and a promotion pointing at a removed page fails that plainly. It is a feed problem: Merchant Center crawls the landing page and compares, and an inconsistency between feed and landing page gets the item disapproved, quietly, one product at a time. And it is a consumer law problem, which is the one that actually costs money.
Under the EU's Price Indication rules as amended by the Omnibus Directive, when you announce a price reduction you must state the prior price, and the prior price is defined as the lowest price applied in the preceding thirty days. Bird & Bird have a good walkthrough of how strictly that is being read. A strikethrough left standing after a sale ends is a claim about a prior price that you are no longer able to substantiate — and on the same shop I found a second, unrelated case where a "was" price sat above what the product had genuinely sold for two months earlier. Different cause, same legal shape.
I have written before about refusing to ship a countdown on an offer that had no end. This is that argument from the opposite direction. There, the device claimed an urgency that wasn't real. Here, the device claimed a saving that wasn't real. Both come from the same habit: treating a persuasion element as decoration rather than as a factual claim you have to be able to defend.
What I changed, and what I didn't
The immediate fix is boring: either extend the sale properly in the shop so the charged price matches what is displayed, or strip the display. Both are fine. Being twenty euros apart is not. That decision belongs with the business, not with me, and it went to them the same day with the cart evidence attached, because "your homepage disagrees with your checkout" is a sentence nobody argues with.
In the ads account, the promotions got detached rather than deleted — same instinct as always, reversible beats decisive — and the two broken sitelinks were swapped for live pages.
The part I'm keeping is the check. The prices across every market and every shop now get read the way a customer reads them: not from the feed, not from the admin, but by loading the live page from outside the network and then putting the thing in the cart. Displayed price and charged price are two different numbers until you prove otherwise, and only one of them is the one you're legally making a claim about. This is the same lesson as checking the tag at the edge rather than in the console: verify where the customer is standing.
Set the end date. Then go and look at the cart.
Sources & further reading
External: Google Ads Help — about promotion assets · Google Advertising Policies — destination requirements · Google Merchant Center — inconsistency between feed and landing page · Bird & Bird — transparency of price reductions in the EU
Related posts: The design asked for a countdown · The GTM snippet was gone from the page · Forty-six live ads, no page to land on · Most of their buyers are over 55