Share

What bad schema costs you

The visible cost is a lost rich result, such as a breadcrumb trail or a product or event feature in the listing. The less visible cost is accuracy. Google says it uses structured data to understand the content of a page and to gather information about the world in general, so your markup is part of how Google pictures your business: what it does, where it operates, who works there. Nobody reads JSON-LD the way they read a homepage headline, so a contradiction in it can sit unnoticed for years.

The page itself can look perfect. Clear copy, fast load, good design. Meanwhile a script tag describes a different service, a different city or a rating nobody has updated in two years, and none of it throws a validation error.

Markup that describes content visitors can't see

Google's structured data policies put it plainly: "Don't mark up content that is not visible to readers of the page," and structured data "must be a true representation of the page content." A Service block listing five services when the page describes three breaks that rule. So does a price range in the markup that appears nowhere in the copy.

Redesigns cause most of these. The visible page gets rewritten and trimmed, while the schema block, sitting in a template file or a plugin setting nobody remembers configuring, stays as it was. Six months later the page describes one business to visitors and an older version of it to crawlers. Team pages are a common case, where the page gets updated and the Person markup still lists someone who left a year ago.

Work With John

If your site isn't bringing in inquiries, that's fixable.

I work with US service businesses and B2B brands on SEO, websites and lead follow-up. On a free strategy call, I'll tell you what's holding your site back, without a sales pitch.

Get a Free Audit

Template schema nobody customized

Themes and SEO plugins often ship schema baked in. A LocalBusiness template arrives with a generic business type, an address format copied from a tutorial example, sometimes an aggregateRating block with numbers that come from nowhere. The owner never wrote a line of it, so nobody thinks of it as something to audit.

Any rating or review count in your markup should trace back to real reviews shown on that page. If it doesn't, delete it. Under Google's policies, a structured data manual action costs the page its eligibility for rich results, and invented ratings are exactly the kind of markup that invites one.

Stacking business types with no clear primary

Some sites set @type to an array of five or six types (LocalBusiness, ProfessionalService, Service, Organization and something custom) on one block, hoping one of them sticks. Schema.org supports inheritance, and some combinations are legitimate. Piling up unrelated types adds no information. It makes the markup harder to interpret and easier to contradict.

Choosing the right type resolves most of this, and I cover that decision in Service schema vs LocalBusiness schema. Pick the most specific type that matches the business, fill in its required and recommended properties, and resist adding extra types as insurance.

Review markup that breaks Google's rules

Review schema has narrower legitimate uses than most owners assume. Google's review snippet guidelines contain three rules that catch service businesses out.

First, self-serving reviews don't qualify. If a business controls the reviews about itself, its LocalBusiness or Organization markup is ineligible for stars, and that includes reviews shown through an embedded third-party widget. Google introduced this rule in 2019, which is why a plumber's own website shouldn't expect star ratings next to its homepage listing.

Second, "Don't aggregate reviews or ratings from other websites." Copying your Google Business Profile rating into your site's markup is precisely what that rule forbids.

Third, marked-up reviews have to be visible on the page, and for a local business, ratings must come directly from users.

So the honest options for most service businesses are to skip review markup on pages about your own business, or to keep testimonials as visible content without star markup. Your real reviews still do their job on your Google Business Profile, which is where buyers see them in local results. What E-E-A-T measures explains why trust signals hold up only when they're genuine.

A worked example: the stars that never show up

Say a business owner installs a review plugin, sees valid aggregateRating markup in the page source and waits for stars that never appear in search results. Start with Google's Rich Results Test rather than a generic validator, because it reports what Google can show as well as whether the syntax parses.

If the test detects the review markup and nothing appears in search, check the markup against the three rules above. Is the reviewed item the business itself? Are the ratings pulled in from another site? Is the rating visible on the page? For a service business reviewing itself, the first question usually settles it, because the markup was never eligible. The fix there is to stop expecting stars and make sure the markup is accurate, or remove it, rather than to tweak the code.

A related problem shows up when a review integration stops syncing. The markup keeps serving an old rating count that no longer matches what the page displays. That's a visible-content mismatch, and the fix sits in the integration feeding the markup, not in the JSON-LD.

FAQ markup after Google retired FAQ rich results

In 2023, Google limited FAQ rich results to well-known, authoritative government and health websites. In May 2026 it stopped showing them in Search altogether. So the generic FAQ accordion added to a service page purely to earn a dropdown in the results earns nothing now.

FAQ content can still help visitors when it answers questions your customers ask. Keep it when it does. Remove the three or four templated questions a plugin installer wrote to satisfy a checklist, because they do nothing for the person reading the page.

When two plugins write schema for the same page

This is the most common technical mess. An SEO plugin generates LocalBusiness markup, a review plugin adds its own aggregateRating block and the theme ships an Organization block in its header template. None of the three developers knew the others would be on your site.

View the page source and count the application/ld+json script tags. More than one or two deserves a look. It isn't automatically a problem, but it's a reliable sign nobody has reviewed the whole picture in a while. Google reads every valid block it finds, so a conflict between them throws no error. Google is left to decide which version to believe.

The cleanest fix is one deliberate source of schema instead of whatever plugins happen to be installed. A platform move is often the moment this gets sorted, as covered in moving from WordPress to Next.js, because moving off a plugin-heavy CMS forces someone to look at what schema was shipping.

Validate with both tools, and know what each one checks

The Schema Markup Validator checks your JSON-LD against the full schema.org vocabulary. The Rich Results Test checks only the subset Google uses for rich results, and it flags missing required properties for those features. They sometimes disagree about the same block, which is useful information. A property can be valid schema.org that Google ignores for search.

Use the Rich Results Test for anything you're doing to earn a rich result, and the validator as a syntax check. Run both on the live page rather than a staging copy, since staging often carries different data. Neither tool checks whether the markup is true, which is why fabricated ratings and stacked types pass both.

Keep schema in the same review cycle as the page

Most of these mistakes happen because schema lives in a part of the codebase nobody revisits when the visible page changes, even when everyone involved knows the rules. When a service page gets updated, its schema should be part of the same review. More on that gap in the technical work nobody sees.

A simple log helps. Record the page URL, schema type, date last verified and the source of any numbers such as prices. It turns "has anyone checked this lately?" from a guess into an answer. Pull it out whenever a redesign or migration is planned, because migrations orphan schema more reliably than anything else: a developer moves the template to a new component structure, confirms the page renders, ships it, and the code generating the JSON-LD keeps reading fields that no longer exist in the new data model. The page looks fine. The schema stays broken until someone runs a Rich Results Test for an unrelated reason.

If your schema hasn't been checked since it was added, treat it as due, the same way you'd treat a sitemap or robots.txt file nobody has opened in a year. A broader pass across crawling, indexing and markup together is part of my SEO consulting work. Read it alongside does schema markup help SEO, since knowing what schema can and can't do sets how much time it deserves. More breakdowns like this one sit in the Technical SEO archive.