"Review has multiple aggregate ratings": one item rated twice in your markup

An item can have one aggregate rating: a single average and a single count. This error means Google found two or more aggregateRating objects attached to the same thing and cannot tell which to show. The usual cause is two plugins, or a plugin and the theme, each marking up the same product.

Search Console reports it in the Review snippets report. While the error stands, the page is not eligible for star ratings in results.

What it looks like

Before

html
{
  "@type": "Product",
  "name": "Stoneware mug",
  "aggregateRating": [
    { "@type": "AggregateRating", "ratingValue": "4.6", "reviewCount": "38" },
    { "@type": "AggregateRating", "ratingValue": "4.8", "ratingCount": "112" }
  ]
}

After

html
{
  "@type": "Product",
  "name": "Stoneware mug",
  "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.6", "reviewCount": "38" }
}

How one item ends up with two ratings

There are three shapes this takes in the page source.

An array inside one object, as in the example above. Rare, and generally produced by custom code merging two data sources.

Two separate blocks describing the same item. One Product in the SEO plugin's JSON-LD and another in WooCommerce's or a reviews plugin's, each with its own aggregateRating. When both use the same @id, or Google otherwise concludes they are the same entity, the ratings are combined onto one item.

JSON-LD plus microdata. The theme's product template has itemprop="aggregateRating" attributes in its HTML while a plugin prints JSON-LD. Both are structured data; Google reads both.

In each case the numbers usually disagree, because the sources count differently: one includes only verified-buyer reviews, another imports ratings from an external platform.

Locate every rating on the page

code
curl -s https://example.com/shop/stoneware-mug/ > page.html
grep -o 'aggregateRating' page.html | wc -l
grep -c 'itemprop="aggregateRating"' page.html
grep -o '<script type="application/ld+json"[^>]*>' page.html | wc -l

The first count is the total number of mentions, the second the microdata ones, and the third the number of JSON-LD blocks. Then open the page in the Rich Results Test, which lists each detected item; expand Review snippets and note the ratings attached.

To identify who prints what, look at the surrounding markup: plugins often add a class or HTML comment naming themselves next to their script, and theme microdata sits in the product template. If that is inconclusive, deactivate suspects one at a time on a staging copy and recount.

Choose the source to keep

Keep the rating that matches what visitors see on the page. Google's review snippet guidelines require the marked-up rating to be visible to users and to come from reviews collected on that page or site. That rules out:

  • A rating imported from a third-party platform when the page shows your own on-site reviews.
  • A site-wide or brand-level rating repeated on every product.
  • A hard-coded sample value left in a theme demo.

For most shops, the native WooCommerce review data is the one to keep, since it is what the product page displays.

Remove the others

  • Reviews or schema plugin duplicating WooCommerce: look for a setting such as "output product schema" or "add rich snippets" and switch it off in one of them.
  • SEO plugin duplicating a dedicated source: disable the Product type for that post type in the SEO plugin, or let the SEO plugin own it and turn the other off. In Hydrogen SEO, schema types are assigned per post type and can be changed per post; see the schema markup overview.
  • Theme microdata: remove the itemprop, itemscope and itemtype attributes from the template in a child theme, or use the theme's option to disable built-in schema if it has one. Leave the visible stars and text in place.
  • Custom code: when merging data, assign a single object to aggregateRating, never an array.

Removing one whole duplicate Product block is cleaner than removing only its rating, because duplicates tend to conflict on price and availability too, and a block with no offer and no rating triggers Either 'offers', 'review', or 'aggregateRating' should be specified.

Individual reviews are fine

The error concerns aggregateRating, the summary. A product can list many individual review objects, each with its own reviewRating, next to one aggregateRating. Do not delete individual reviews to fix this. Check instead that each Review contains reviewRating, not a nested aggregateRating, which is a common slip in hand-written markup. The review snippet reference shows the correct nesting.

Validate the result

  1. Recount with the grep commands: one aggregateRating, in one format.
  2. Paste the remaining block into our JSON-LD validator to confirm it parses and has ratingValue plus reviewCount or ratingCount.
  3. Run the Rich Results Test: Review snippets should show one valid item.
  4. In Search Console, open the Review snippets report, select the error and click Validate fix.

Stars may take some time to reappear after validation passes, and they are never guaranteed; review stars not showing covers the other reasons.

Common questions

Can a page have ratings for several different products?

Yes, each product can have its own aggregateRating. The error is about one item with more than one.

Which rating does Google use if I leave both?

Neither. The item is invalid for review snippets until only one remains.

Is ratingCount or reviewCount required?

At least one of them, together with ratingValue. Use reviewCount for written reviews and ratingCount for star-only ratings.

Do I need to remove the visible stars from my theme?

No. Only the duplicate structured data. Visible ratings should stay, since the markup must match what users see.