Skip to main content
SEO

Shopify Product Schema Errors: What to Fix, What to Skip

Which Search Console Merchant listings and Product snippets warnings block eligibility on Shopify, which are optional, and how shipping and returns data works.

November 4, 2026 17 min read Talha Butt.
Share

Shopify Product Schema Errors: What to Fix, What to Skip

Quick answer: In Google’s merchant listing documentation, a product page needs only a few things to be eligible: a name, an image, and an offer with a price above zero and a currency. Availability, shipping details, return policy, priceValidUntil, product identifiers and reviews are all listed as recommended, so Google does not make them a condition of eligibility. Shopify’s documented example output carries price, currency and availability, but on the public Shopify demo store I checked on 31 October 2026 it carried no shipping or return data, so expect those two warnings on a store using the standard output. Fix critical errors first, supply shipping and returns once for the whole store, and treat the rest as decisions.

You open Search Console, go to Shopping, then Merchant listings, and there is a list of warnings that name fields such as shippingDetails and hasMerchantReturnPolicy. Some of them look serious. Search for the wording and the advice you find is all over the place.

This guide reads the reports one field at a time against Google’s own documentation: which fields decide eligibility, which are optional, what Shopify outputs by default, and how shipping and return policy data gets supplied. It covers on-site structured data only. Product feeds are a separate subject. Structured data that AI shopping answers can read is part of our AI SEO service.

I am not going to promise that clearing warnings changes your rankings or sales. Google says it does not guarantee that features using structured data will show. The case for doing the work is narrower: the data Google reads should match the page a shopper sees, and the few gaps that really block eligibility should be closed.

The two reports, and which one your product pages land in

Search Console has two product reports, and they sit under Shopping, not under Enhancements, according to Google’s help.

  • Merchant listings. For pages where shoppers can buy the product from you. Google’s product overview says this markup has more options for detail such as shipping and return policy information, and Search Console’s help says these listings always include a price.
  • Product snippets. For product pages where people cannot buy directly, such as review pages and aggregator sites. Google’s overview says that adding the required merchant listing properties generally makes a page eligible for product snippets too, so the two overlap.

A store that sells its own products should read the Merchant listings report. Google’s merchant listing page says that report already includes checks for product snippets that carry an Offer, so the Product snippets report only needs a look for pages that are not for sale, such as review-style pages about products you do not sell.

Two details from Google’s Shopping reports help are worth knowing before you open either.

  • A report only appears if Google found that markup. A rich result report appears only if Google finds valid markup of that type. If the report exists but the “Merchant opportunities” report does not, Google found structured data but did not recognise the site as an online shop for physical goods.
  • Google decides whether you count as an online merchant. The help says sites that redirect users elsewhere (affiliate sites), or do not allow purchase completion on the site, are not considered online merchants for Search Console’s reporting purposes. A normal Shopify store with a working checkout is not in that group.

As at 31 October 2026, Google’s merchant listing, product snippet, variants, shipping policy and return policy pages each showed a last-updated date of 8 September 2026. Check those dates again before acting on any rule below.

Critical versus non-critical: the only sorting rule you need

Search Console’s rich result report help defines two groups. A valid item has no critical issues and can appear as a rich result. An invalid item has at least one critical issue, listed under “Why items are invalid”, and those issues prevent Google using the structured data. Non-critical issues are listed under “Improve item appearance”. An item can carry both kinds at once.

Google’s merchant listing documentation says the same in its implementation steps: validate with the Rich Results Test and fix critical errors. Fixing non-critical issues is worth considering, but Google says it is not necessary to be eligible for rich results.

The Google pages I read do not publish a list of exact issue names or say which message maps to which group, so I will not pretend to give you one. What they do publish is which properties are required and which are recommended, and that is the guide to use. Then check the heading each issue sits under in your own report before you decide how urgent it is.

This table compares the fields that come up most in Shopify reports. It is based on Google’s product snippet and merchant listing documentation as at 31 October 2026.

FieldProduct snippetsMerchant listings
nameRequiredRequired
imageNot listedRequired
offers (a single Offer)One of review, aggregateRating or offers requiredRequired; AggregateOffer not accepted
priceRequired inside offers; 0 allowedRequired; must be greater than zero
priceCurrencyRecommendedRequired
availabilityRecommendedRecommended
priceValidUntilRecommendedRecommended
shippingDetails, hasMerchantReturnPolicyNot coveredRecommended
aggregateRating, reviewRecommended (one of the three is required)Recommended

The other fields that come up (brand, sku, gtin, mpn, description, color, size, itemCondition, url) are also listed as recommended for merchant listings, not required.

Price: the field that can actually block you

For merchant listings, Google requires a price greater than zero and a three-letter currency code. It accepts the price either as offers.price or inside a priceSpecification, and if both carry the active price, it uses offers.price.

The detail worth checking on a Shopify catalogue is the greater-than-zero rule. Google’s merchant listing page says plainly that, unlike product snippets, merchant listing experiences require a price greater than zero, and the product snippet page allows 0 for a product available without payment. If you sell a free gift, a sample or a zero-priced add-on as its own product, that offer does not meet the merchant listing requirement. I did not test how Search Console labels it, so read the heading it sits under. Whether you want a free item to be a merchant listing at all is a separate decision, and usually you do not.

Two other price rules are worth knowing:

  • Do not put a priceType on the active price. Google’s wording is “Don’t mark the active price with a priceType property”. It reserves priceType for strikethrough prices (the higher regular price shown during a sale), and says a price specification that carries both a priceType and a member tier is ignored.
  • Marked-up prices must match the page. Google’s merchant listing page says it may attempt to verify merchant listing product data before showing it. Its general guidelines say not to mark up content that is not visible to readers and that markup must be a true representation of the page. They do not single out price, but a marked-up price that differs from the visible price is plainly the kind of mismatch they describe.

It is easy to assume that missing availability blocks eligibility. In Google’s merchant listing and product snippet documentation, it does not. Availability is recommended, and Google asks for one value from the schema.org list, such as in stock, out of stock, pre-order or discontinued. Short names without the URL prefix are accepted.

That does not make it unimportant. A shopper who sees “in stock” in a result and lands on a sold-out page has had a poor experience, and Google’s guidelines say markup must reflect the page. The practical check is that your markup says out of stock when the page does. On the Shopify demo store I checked, a product whose page showed “Sold out” had OutOfStock in the markup for all five of its variants, which is what you want.

Some vendor blogs present priceValidUntil as something Google demands. Google’s documentation lists it as recommended, in ISO 8601 date format. What it warns about is a date in the past: “Your listing may not display if the priceValidUntil property indicates a past date.”

So the risk is not leaving it out. The risk is a theme or app that hard-codes a date once, and then the date passes. If you see it in your markup, check what date it holds and who updates it. For sales, Google’s sale duration section says the end of the sale can be given with validThrough or priceValidUntil, and best practice is to give both a start and an end. It also says priceValidUntil is not applicable to a price specification, where validThrough is used instead.

If you run a sale and your markup carries an end date, it needs to match the real end of the sale. Our Black Friday checklist covers the rest of the sale preparation.

What Shopify outputs by default

Shopify provides a Liquid filter called structured_data. Shopify’s developer documentation says it converts a product into schema.org markup you can place in a JSON-LD script tag. A product with no variants comes out as a Product, and a product with variants comes out as a ProductGroup. Shopify’s own example output includes the name, image, brand, and an Offer with availability, price, currency and a URL. It does not list shipping details, return policy or priceValidUntil in that example.

Shopify’s reference theme, Dawn, uses that filter on the product page. On the main branch of the Dawn repository on 31 October 2026, the product section prints {{ product | structured_data }} inside a JSON-LD script tag. Your theme may be a paid theme or an older version, so it may do something different.

I also read the live markup on a public Shopify demo store (os2-demo.myshopify.com) on 31 October 2026. For a multi-variant product it printed a ProductGroup with each variant as a nested Product, each with its own Offer containing availability, price, currency and a variant-specific URL. It printed no shippingDetails, no hasMerchantReturnPolicy and no priceValidUntil, and the variant products carried no sku or gtin. That is one demo store, one product, one day, so it shows what the filter can produce, not what your store does.

In the output I read, the fields Google requires for merchant listings were present, and the shipping and returns fields Google lists as recommended were not. So on a store using the standard output, those two warnings are what you would expect to see. I have not seen your Search Console, so check it rather than assume.

How to check your own store in two minutes

  1. Open a product page in your browser, view the page source, and search for application/ld+json. Count the blocks. On the demo store there were two: one for the organisation and one for the product.
  2. If you find two product blocks, find out why. A theme and an app can each print one. A Shopify Community thread from October 2024 describes a store whose “missing description” message traced to two competing product blocks, only one of which carried a description. That is one forum thread, not Google’s documentation, so treat it as a lead to check, not a rule.
  3. Paste the product URL into Google’s Rich Results Test, which tests a publicly accessible page for the rich results its structured data can generate. Note which items are flagged as critical.
  4. Compare the markup to the visible page: price, currency, availability, name and main image.

Google also says to place product markup in the initial HTML where possible. Markup generated by JavaScript after the page loads can make Shopping crawls less frequent and less reliable, which matters for data that changes quickly, such as price and stock. Dawn prints the filter’s output straight from the theme template, not through JavaScript. The thing to check on your store is whether any app adds its own product markup in the browser.

Shipping and return policy: how the data gets supplied

Here is what Google’s documentation says about where this data comes from.

Google reads policy data from several places, and has a pecking order

For shipping and returns, Google’s merchant listing page lists these sources from strongest to weakest:

  1. Product-level feeds submitted in Merchant Center
  2. Settings in the Content API for Shopping
  3. Settings in Merchant Center or Search Console
  4. Product-level merchant listing markup
  5. Organisation-level markup

(Google’s separate return policy and shipping policy pages give the same order without the feeds line.) Where settings in Search Console exist as well as markup on your site, those two pages say Google will only use the information provided in Search Console. So if some other system already supplies your shipping and returns data to Google, adding markup on the site may make no difference to what is shown, and two sources that disagree are worse than one. A missing-field warning describes your markup. It does not tell you whether Google has policy data from somewhere else, so check where else yours is supplied before you assume it is blank.

What Google wants in the markup

Google separates a standard policy from exceptions.

  • A standard policy that covers most products goes at organisation level. Returns use hasMerchantReturnPolicy under your Organization, and shipping uses a ShippingService under Organization via hasShippingService. Google recommends putting this on one policy page, not repeating it on every page.
  • Exceptions for a specific product go on the offer, using hasMerchantReturnPolicy and shippingDetails. Offer-level markup supports fewer properties.
  • If you provide both, Google defaults to the product-level policy for returns.

For return policies, the required properties are applicableCountry (up to 50 countries) and returnPolicyCategory, which is one of a finite return window, not permitted, or unlimited window. If you choose a finite window, merchantReturnDays is also required. Google offers an alternative: a merchantReturnLink pointing to a page that describes the policy. Return fees, return method, refund type and restocking fee are recommended.

For offer-level shipping details, the properties Google lists as required for the shipping enhancement are the shipping rate (a value and a currency matching the offer, with 0 meaning free), a shipping destination country, and a delivery time. Within the delivery time, a handling time and a transit time are recommended, each given as a range of whole days. Google supports regions and postcodes for some countries: it currently supports region codes for the US, Australia and Japan, and postcodes for Australia, Canada and the US.

A structural example

Below is an illustrative offer-level example for a fictional Australian store. The numbers are placeholders to show the structure. They are not a suggested policy, and every value must match what your shipping and returns pages actually say.

"offers": {
  "@type": "Offer",
  "price": "49.00",
  "priceCurrency": "AUD",
  "availability": "https://schema.org/InStock",
  "shippingDetails": {
    "@type": "OfferShippingDetails",
    "shippingRate": { "@type": "MonetaryAmount", "value": 9.95, "currency": "AUD" },
    "shippingDestination": { "@type": "DefinedRegion", "addressCountry": "AU" },
    "deliveryTime": {
      "@type": "ShippingDeliveryTime",
      "handlingTime": { "@type": "QuantitativeValue", "minValue": 0, "maxValue": 1, "unitCode": "DAY" },
      "transitTime": { "@type": "QuantitativeValue", "minValue": 2, "maxValue": 5, "unitCode": "DAY" }
    }
  },
  "hasMerchantReturnPolicy": {
    "@type": "MerchantReturnPolicy",
    "applicableCountry": "AU",
    "returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
    "merchantReturnDays": 30,
    "returnMethod": "https://schema.org/ReturnByMail",
    "returnFees": "https://schema.org/ReturnFeesCustomerResponsibility"
  }
}

A flat rate like this suits a store with one simple shipping rule. If your rates vary by order value, weight or zone, a single fixed number in markup would be wrong for some orders. In that case follow Google’s shipping policy page for the organisation-level structure, which uses shippingConditions to express conditions, or leave shipping out of the markup rather than publish a number that is sometimes false.

Rules that prevent most mistakes

  • Match the page. Your shipping and returns pages are the source of truth. If the markup says 30 days and the policy page says 14, one of them is wrong, and Google’s guidelines say markup must reflect the page. Whether the policy itself is lawful for Australian consumers is a separate question for a professional. This guide is not legal advice, and markup does not make a policy compliant.
  • One source of truth. Update the policy page and the markup together. A policy that changes in January while the markup still carries the old window is an easy way for the two to drift apart.
  • Do not add what you cannot keep true. Google lists these fields as recommended. A wrong value is worse than a missing one.
  • Keep it to one block per product. Add policy data to the existing product block, or to a single organisation block, not a second competing product block.
  • Theme edits need care. Duplicate your theme, make the change there, test it with the Rich Results Test, and publish only when the result is clean. If you are not comfortable editing Liquid, this is a job for a developer.

Our guide to shipping and returns messaging for Australian Shopify stores covers the visible side: what shoppers need to see on the page. The markup should echo that, never the other way round.

Variants, sale prices and currencies

Three Shopify-specific points come up in these reports.

Variants. Google’s variants documentation says you can group variants with a ProductGroup, with each variant nested as a Product, which is how Shopify’s output is shaped. It says each variant must have a unique ID in its markup (for example sku or gtin), each product group must have one too (productGroupID), and each variant also needs the standard product markup. The demo output I read had a productGroupID but no sku or gtin on its variants, so if your variants have SKUs, check that they appear in your markup. Google also requires that each variant can be pre-selected with its own URL, and Shopify’s ?variant= addresses appear in the demo output as offer URLs. For single-page sites, its documentation says there should be one canonical URL for the whole group, typically the base URL with no variant pre-selected. For how those URLs should be treated for indexing, see our guide to duplicate content and canonical URLs.

Sale prices. Google supports a strikethrough price: a higher regular price marked with a price type, shown during a sale. In the Shopify output I read, only the current price appeared. If you want a compare-at price recognised, it needs extra markup, and it is only appropriate when the higher price is a price you genuinely charged. The advertising-law side of “was” prices is covered in the Black Friday checklist linked above.

Currencies. Google’s guideline is a distinct URL per currency. If you sell in AUD and USD through markets, check how your setup serves the second currency before you assume the markup covers it.

A triage order that works

  1. Open the Merchant listings report and start with the “Why items are invalid” table. Those are the critical issues. Nothing else matters until they are cleared.
  2. Group the affected URLs by type. Free or zero-priced products, products with a missing image and products from a particular template behave differently. Google’s help says that if an error comes from a template, fixing the template resolves all the pages that use it.
  3. Fix one issue across all URLs before starting the next. Google’s own workflow says exactly this.
  4. Test the live URL. Use the URL Inspection tool’s live test, or the Rich Results Test, before you ask for validation.
  5. Click Validate fix once. Google checks a sample first and continues only if the sample passes. It says validation can take two weeks or more, depending on how often it crawls your pages. Do not restart it before the cycle finishes.
  6. Then turn to “Improve item appearance”. Decide per field: supply it, supply it once for the store, or leave it.
  7. Check Unparsable structured data. Google’s help says that report lists structured data with a serious syntax error, so the type could not even be determined. It only appears if Google found such markup, and because the type could not be determined, those items are separate from your merchant listings report.

A worked example (illustrative numbers)

These numbers are made up to show the method. They are not from a real store. Say a store has 220 product URLs in the Merchant listings report:

GroupURLsWhat it isDecision
Zero-priced products6Free gifts and samples set up as productsRequired price rule not met. Decide whether a free item should carry sellable-product markup at all
Missing shipping details214Warning onlySupply once at store level, or leave
Missing return policy214Warning onlySupply once at store level, with the real window
priceValidUntil in the past40An app printed a fixed date last yearRemove the field, or make it dynamic
Missing GTIN150Warning onlyAdd real GTINs where the brand has them; leave the rest

The 214 “missing” warnings are really two jobs, not 428 separate problems. The 6 zero-priced products are the only ones failing a requirement. The 40 expired dates are the ones that could suppress the listing, since Google warns a past date may stop it showing. The urgent work is in 46 URLs, not 220.

What fixing this does not do

A clean report means the markup parses and meets the field rules. It does not mean Google will show a rich result: Google says shopping experiences are shown at its discretion and may change over time. Valid markup makes a page eligible, and no one can honestly promise what it will do for traffic or sales.

Two further limits apply:

  • Quality rules apply after the syntax passes. Google says that violating its quality guidelines, such as marking up content that is not visible to readers, can stop correct markup from showing as a rich result. A structured data manual action causes the markup on the page to be ignored.
  • Reviews have their own rules. Review and rating markup follows Google’s separate review snippet guidelines, which this post does not cover. See product reviews, star ratings and SEO on Shopify.

For the wider picture, schema markup and AI citations covers how markup relates to AI answers, and our product page SEO checklist puts schema in the context of everything else a product page needs. Both sit inside the Shopify SEO, GEO and CRO resource hub. If AI summaries matter for your category, AI Mode and AI Overviews for ecommerce explains what to check.

Key takeaways

  • For merchant listings, Google requires a name, an image, and an offer with a price above zero and a currency. Availability, shipping, returns, priceValidUntil, GTINs and reviews are recommended.
  • Critical issues are the ones that make an item invalid. Non-critical issues sit under “Improve item appearance”, and Google says fixing them is not necessary for eligibility.
  • Zero-priced products are worth a check: product snippets allow a price of 0, merchant listings need a price above zero.
  • priceValidUntil is recommended, not required. The risk is a past date left in the markup.
  • Shopify’s documented example output includes price, currency and availability. In the demo store output I read, it had no shipping, return policy or priceValidUntil.
  • Supply shipping and returns once, at store level, with values that match your policy pages. A wrong value is worse than a missing one.
  • If settings in Search Console or Merchant Center already supply this data, Google uses those over on-site markup.
  • Fix one issue across all URLs, test live, click Validate fix once. It can take two weeks or more, and a clean report is not a guarantee of a rich result.

FAQs

Are missing shippingDetails and hasMerchantReturnPolicy warnings errors I have to fix?

Not to be eligible. In Google’s merchant listing documentation both are recommended properties. Check the heading each message sits under in your report to confirm it is non-critical. They are worth supplying if you can keep the values true. If your policy changes often or varies by zone, leaving them out is better than publishing a wrong number.

Does a missing availability field stop my products showing in merchant listings?

According to Google’s documentation, no. Availability is recommended for both product snippets and merchant listings. The fields to watch are price, which must be greater than zero, and the currency. Shopify’s documented example output includes availability, and the demo store I checked set it to out of stock on a sold-out product.

Is priceValidUntil required on Shopify?

No. Google lists it as recommended, and warns that a listing may not display if it holds a past date. If your theme or an app prints a fixed date and you cannot keep it current, remove it.

Why does my product have a price in the report but get flagged for price?

Two causes you can check against Google’s documentation. One is a price of zero: merchant listings need a price greater than zero, while product snippets accept zero for free products. The other is a price specification that carries both a price type and a member tier, which Google ignores, so make sure you have not marked your active price that way. Run the live URL through the Rich Results Test and read the exact item flagged.

If I add shipping and returns markup, will it override my other settings?

No. Google ranks markup below product-level feeds, Content API settings and settings in Merchant Center or Search Console, and organisation-level markup ranks last of all. When Search Console settings exist, Google says it uses only those. On-site markup is for stores that supply the data nowhere else, or that want the page to state the same facts.

How long until the warnings clear after I fix them?

Google says it may take several days after publishing for a page to be found and crawled, and that Validate fix can take two weeks or more depending on how often it crawls your pages. Start validation once, after the fix is live on every affected page.

Will fixing product schema improve my rankings?

Nobody can promise that. Google says it does not guarantee that features using structured data will show up in search results. Valid markup makes a page eligible for richer results and keeps what Google reads in line with the page. It is not a ranking guarantee.

Want a second pair of eyes on your product markup?

Structured data is one part of the technical audit in our Shopify SEO service. It sits alongside crawlability, indexation and speed, because a perfect product block on a page Google cannot index helps nobody. If you would like us to look at your store, book a free 30-minute diagnostic or tell us about your store. We look at your store before we recommend anything, and we tell you honestly if SEO isn’t the right move. No pitch.

Free 30-min diagnostic

Seen enough?
Book a free diagnostic.

We'll look at your store's search pages, find what is costing you traffic and tell you what to fix first. No pitch. No email gate. 30 minutes.

More from Prism3