You search your own product on Google, or check a Shopping result, and the price shown doesn't match what's actually on your Shopify store — sometimes an old price from before your last change, sometimes no price rich result at all. Nothing is wrong in Shopify admin: the product is active, the price field is correct, checkout charges the right amount. The mismatch only exists on Google's side.
This is a real, recurring complaint in the Shopify Community — merchants report Google holding onto a stale price for sold-out or repriced products for days or weeks, with generic advice ("wait for Google to recrawl," "hit Fetch Now") that treats the symptom but not the underlying cause. In our scans, the underlying cause is almost always structural: the product's JSON-LD is missing the one field that tells Google how long a price stays valid.
How to confirm it yourself in 5 minutes
- Run a
site:search for the affected product URL and compare the price shown in the snippet against your live storefront price. - Paste the same URL into Google's Rich Results Test and open the detected
Productmarkup — check theoffersobject for apriceValidUntilfield and whether its date is in the future. - In Google Search Console, open Enhancements → Merchant listings and check for any warnings logged against the affected URL — this report tracks Product structured data issues separately from an actual price-mismatch error.
- If you also run Merchant Center for Shopping ads, check its Diagnostics tab for "mismatched value (price)" — that's a related but distinct feed-level issue, not the same as this Search-side symptom.
Want this checked automatically? We inspect the Offer/price schema on every product page in your catalog — read-only, no admin access, about 2 minutes. → free scan
Causes, ranked by how often we actually see them
1. priceValidUntil is missing from the product's structured data entirely. This is by far the most common cause: in our aggregated scans across 822 Shopify stores, 514 (62%) have no price_valid_until value at all. That's not a merchant mistake — Shopify's own structured_data Liquid filter, the built-in filter Dawn and most modern themes use to generate Product JSON-LD, outputs an offers object with availability, price, priceCurrency, and url — no priceValidUntil. It has to be added manually via a theme edit or an app. Without it, Google's Offer object has no explicit signal for how long the current price should be trusted, and per Google's own merchant listing documentation, it's a recommended property of the Offer type — it isn't required for basic eligibility, but its absence removes one of the freshness signals Google uses to decide whether to trust and (re)display a price.
2. priceValidUntil was set for a past promotion and never updated. A sale or discount app writes a priceValidUntil matching the promo's end date, the sale ends, and nothing goes back to refresh or remove that date. Google's documentation is explicit here: "Your listing may not display if the priceValidUntil property indicates a past date." Google separately recommends pairing a start date with the end date specifically for sale pricing, so both ends of the window stay accurate. A leftover expired date is worse than having none.
3. Google simply hasn't recrawled since your last price change. Indexing lag alone can produce a stale price for days to weeks — this is the explanation Shopify Community threads on this exact symptom usually land on, and it's genuine. But it compounds with cause 1: a page with no freshness signal in its Offer data gives Google less reason to treat the price as time-sensitive and prioritize a recheck.
4. Malformed price or currency fields. Less common, but worth a quick check: price must be a bare number string with no currency symbol, and priceCurrency must be a valid ISO 4217 code. A stray symbol or the wrong code can make Google discard the price signal from your structured data entirely and fall back to whatever it last crawled from the visible page.
The fix
- Add priceValidUntil to your theme's Product JSON-LD if it isn't there, computed live rather than hardcoded — most implementations set it to a rolling window (commonly 30 days to a year out) from the current date, recalculated on every render, so it never quietly goes stale on its own:
(the example above adds 30 days; a sale-price app should instead set this to the actual promo end date, and clear or extend it the moment the sale is edited.)"priceValidUntil": "{{ 'now' | date: '%s' | plus: 2592000 | date: '%Y-%m-%d' }}" - Audit any sale/discount app for a leftover expired date — check its settings for a hardcoded promo end date that outlived the promo itself.
- Request reprocessing in Search Console's URL Inspection tool for the affected URL once the fix is live, rather than only waiting for the next organic crawl.
- Validate
priceandpriceCurrencyformatting with the Rich Results Test while you're in there.
None of this shows up as an error anywhere in Shopify admin — the product looks completely correct on your side. The only visible symptom is a shopper-facing price on Google that quietly drifted out of sync with your store, which is exactly the kind of gap that costs a sale before the shopper ever reaches checkout.
Next in this cluster
Not sure if this is happening on your store right now?
Scan my store for free