Every large e-commerce catalogue has the same problem. Product schema that shipped two years ago still validates on the handful of pages somebody checked by hand, and fails on the other forty thousand. Google does not email when markup stops qualifying. The failure stays invisible until a template change wipes out rich results and nobody can explain the drop.
Digital Applied ran 5,000 production sites through Google's Rich Results Test in April 2026 and found that 71% ship at least one schema type, while only 22% pass cleanly across every type they emit. The largest group, 49% of the sample, sits in the middle with markup deployed and markup broken. In e-commerce, 73% of stores emit Product markup, and most of that comes from Shopify theme and WooCommerce plugin defaults rather than deliberate implementation. Emission is the easy half. Keeping the markup true is the part that gets skipped.
Structured data stopped being a checklist item
The old argument for schema was that it earned stars and price chips in the search result. That is still true, and it is no longer the main reason to care. Google retired FAQ rich results on 7 May 2026, ending nine years of question-and-answer chips in the SERP. A whole category of markup that agencies sold as a deliverable now does nothing. What survived is the part that describes an actual entity: Product, Offer, Organization, BreadcrumbList.
The role of that markup has shifted toward verification. Google has confirmed that structured data improves extraction accuracy for AI Overviews, and the 5,000-site audit measured a Pearson correlation of +0.34 between passing the Rich Results Test and being cited in AI search. Product plus Offer combinations showed a 29% citation lift on commercial-intent queries. A correlation of that size is a signal rather than proof, and the audit is careful to say so. It is still the cleanest evidence available that machine-readable, verifiable product data gets picked up more often than the alternative.
What changed in Google's own documentation
Google's merchant listing documentation was last revised on 8 September 2026, and the required field set is stricter than most implementations assume. Name, image and offers with price and priceCurrency are required. SKU, GTIN, brand, description and aggregateRating are recommended, and GTIN does disproportionate work: it is the identifier Google uses to match the same product across the page, the feed and other sources. Without a GTIN, matching falls back to brand and title, which gets imprecise the moment an agent compares three near-identical listings.
The category property is new and worth wiring up. It accepts plain text or a CategoryCode object, so a page can declare both a Google product taxonomy value and the merchant's own category path in one node. That closes a gap that used to sit between what a page said and what a Merchant Center feed said. Sale pricing got similar treatment. A second price marked with priceType https://schema.org/StrikethroughPrice produces the strikethrough automatically, and validFrom, validThrough and priceValidUntil define the window in ISO 8601 with a timezone offset.
Five failure patterns account for most of the damage
The audit clustered errors into five buckets, and every one of them is catchable in a build test rather than a quarterly audit:
- Missing required properties, on 38% of error pages. Usually offer, price or image, dropped when a template branch renders a product with no variants.
- Invalid ISO-8601 dates, on 24%. Hand-written date strings, missing timezones, and priceValidUntil values left in the past by a promotion that ended months ago.
- Wrong type for the page, on 12%. Product markup on a category page, or Article markup on a landing page that is really a product comparison.
- Missing or invalid image dimensions, on 9%. ImageObject without width and height, common when a CDN rewrites URLs and strips the metadata the template used to read.
- Duplicate @id values, on 7%. Two nodes claiming the same identifier, usually a plugin and a theme both emitting Organization markup.
The pattern behind all five is the same. Somebody wrote the markup once, and a template has been regenerating it ever since with no validator in the middle.
Variants are where product schema breaks
A product page with a colour picker and six sizes is not one product, and marking it up as one produces a lie. Google's model for this is ProductGroup with hasVariant entries for each SKU, variesBy to declare the axes, and a shared productGroupID tying the set together. Done properly, the variants stay associated instead of competing as near-duplicates.
Done badly, the more common failure appears: the page displays one preselected variant while the markup describes a different one, or describes a price range. Google validates the markup against the variant that is actually preselected. If a shopper lands on the 2XL at $89 and the JSON-LD says $64 because that is the cheapest size, the listing is inaccurate and the discrepancy can suppress the whole product. Each variant needs its own SKU and its own price, and the server has to render the correct pair for the URL being requested.
Server-rendered markup, not injected markup
Google recommends placing product structured data in the initial HTML the server returns, for a practical reason. Price and availability are the fields that change most often, and they are the fields most likely to be written by client-side JavaScript after hydration. A crawler that renders late, or renders partially, sees whatever the server sent. If the server sent no offers object, the page has no offers object.
The same applies to the number inside it. Caching a product page for an hour is fine until a sale starts and the cached HTML carries yesterday's price into the markup. Consistency between the visible price, the JSON-LD price and the Merchant Center feed is a hard requirement for merchant listings, and it is the one that breaks most often during flash sales and currency switches.
Shipping and returns now sit next to the price
shippingDetails and hasMerchantReturnPolicy used to be optional annotations. They now appear alongside price in merchant listings, which puts them in direct competition with the neighbouring result. Two identical products at the same price get separated by delivery window and return terms, and only one of the two is showing both.
One structural detail catches most implementations. When a store has a single standard return policy, Google recommends nesting MerchantReturnPolicy under Organization rather than repeating it on every product. Product-level policies exist for overrides, and they support a smaller subset of properties than merchant-level ones. Repeating a full policy across 40,000 product pages wastes markup and creates a maintenance trap the first time the policy changes.
Unit pricing runs into the same accuracy problem with more legal weight behind it. For products sold by volume, weight or length, referenceQuantity inside a UnitPriceSpecification expresses the price per 100ml or per kilogram. That is required in the EU, New Zealand and Australia, and it tends to be absent from stores outside those markets until they expand into one.
What the agentic checkout layer actually requires
Google I/O 2026 introduced Universal Cart, a cart that follows a shopper across Search, Gemini, YouTube and Gmail while the retailer stays merchant of record. It runs on the Universal Commerce Protocol, announced in January 2026 and built with Shopify, Etsy, Wayfair, Target and Walmart, with payment backing from Visa, Mastercard, American Express, Stripe and Adyen. Checkout access began in the US through an early access programme, and Merchant Center onboarding was simplified in March 2026.
The detail that matters for anyone maintaining product markup is that schema.org Product markup does not gate the buy button. Eligibility comes from a native_commerce attribute in the Merchant Center feed, set per product, ideally through a supplemental data source so the primary feed is untouched. Product markup still qualifies a page for the merchant listing rich result in organic search, and Google recommends it for crawl quality. Those are two separate pipelines describing the same product, and confusing them leads teams to wait for a checkout button that was never going to appear.
Both pipelines depend on the same underlying data matching. When a purchase can complete inside an AI surface without a human ever loading the product page, stale availability stops being a listing problem. It blocks a transaction.
A validation pipeline that survives template changes
Manual validation does not scale past the first hundred SKUs, and it decays the moment a theme update ships. What works is a pipeline with three layers.
A validator in CI renders each product template, extracts every JSON-LD block, and fails the build on missing required properties, malformed dates, duplicate @id values and schema types that do not match the page. The audit's five error buckets are all catchable this way, and the validator is roughly fifty lines of code against a headless render.
Search Console then gets treated as production monitoring instead of a launch checklist. Merchant listings and Product snippets are two separate reports with different requirements, and only the first checks offers inside product snippets. Pull both through the Search Console API on a schedule and alert on the invalid item count, rather than glancing at the numbers once a quarter.
Coverage gets tracked by template, not by URL. A store with 40,000 SKUs has perhaps six product templates. Validating one live URL per template after every deploy catches the regression that actually happens, which is a field disappearing when a conditional branch stops matching.
Where to start
The sequence that produces results fastest is unglamorous. Export the invalid item counts from both Search Console reports and group them by template. Fix the highest-impression template first, because that is where the lost clicks are. Then wire the CI validator so the fix stays fixed. Then add ProductGroup for variants, shipping and returns, and unit pricing for any market that requires it.
A store that moves out of the broken middle does not get a traffic guarantee. What it gets is eligibility it already paid for and never received, on pages it already ranks, plus a data layer that AI shopping surfaces can read without guessing. That is a smaller promise than most schema pitches make, and it is the one that holds up.