Schema Markup Mistakes That Are Hurting Your Search Visibility

Metallic JSON brackets on dark surface — some rusted and broken, others polished and correct

Last month we audited a Calgary plumbing company's structured data. They had 14 separate JSON-LD blocks across their site. Every single one had at least one error. Google was ignoring all of them.

They'd paid a developer $2,000 to "add schema markup" six months earlier. The developer copied templates from a blog post, swapped in the business name, and never validated anything. The result was 14 blocks of machine-readable code that no machine could actually read. No rich results. No knowledge panel data. No enhanced local pack listing. Two thousand dollars producing exactly zero search value.

We see this pattern constantly. Structured data is one of the few areas where a small technical mistake doesn't degrade performance gradually — it kills it outright. A missing comma in your JSON-LD and Google pretends the entire block doesn't exist. No warning in your search results. No email from Google saying "hey, your schema is broken." Just silence.

If you've added structured data to your site and haven't seen any change in how your pages appear in search results, there's a good chance something is broken. Here's where to look.

Syntax Errors: The Silent Killers

JSON-LD is unforgiving. One wrong character and the entire schema block fails to parse. Google doesn't try to salvage partially valid markup — it discards the whole thing. According to data from structured data auditing tools, roughly 78% of JSON-LD errors come down to simple typos. Missing commas, unclosed brackets, wrong quote types.

Here's a LocalBusiness schema with three errors. See if you can spot them:

{
  "@context": "http://schema.org",
  "@type": "LocalBusiness",
  "name": "Mountain View Plumbing",
  "telephone": "+1-403-555-0198",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "1240 9th Avenue SE"
    "addressLocality": "Calgary",
    "addressRegion": "AB",
    "postalCode": "T2G 0T3",
    "addressCountry": "CA"
  },
  "openingHoursSpecification": {
    "@type": "OpeningHoursSpecification",
    "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
    "opens": "07:00",
    "closes": "18:00",
  }
  "image": 'https://example.com/storefront.jpg'
}

Error one: http://schema.org instead of https://schema.org in the @context. Google has silently ignored entire schema blocks over this single character. Error two: missing comma after the streetAddress value. JSON requires a comma between every key-value pair except the last one in an object. Error three: single quotes around the image URL. JSON only accepts double quotes. Also, there's a trailing comma after "closes": "18:00" that some parsers will reject.

Four problems in 20 lines of code. None of them would produce a visible error on the page. A visitor would never know. Your developer might never know. Google definitely knows.

How to catch these: Use a code editor with JSON syntax highlighting. VS Code, Sublime Text, even the free web-based JSON Lint will flag bracket mismatches and missing commas instantly. Colour-coded syntax highlighting makes mismatched quotes visible at a glance. Never write JSON-LD in a plain text editor or directly in a WordPress custom field without validation.

Missing Required Properties

Google's documentation is explicit: if a required property is missing, the item is not eligible for rich results. Period. Not "might still work." Not "degrades gracefully." Not eligible.

The tricky part is that "required" differs by schema type. A LocalBusiness needs name and address at minimum. But if you want that business to appear in local rich results with hours and contact info, you also need openingHoursSpecification, telephone, and image. Google lists image as required for LocalBusiness rich results — and we've seen more audit failures on missing images than any other single property.

Here's a quick reference for the schema types we implement most often:

LocalBusiness required for rich results: name, address, image. Strongly recommended: telephone, openingHoursSpecification, geo, url, priceRange.

FAQPage required: mainEntity (array of Question objects), each with name and acceptedAnswer containing text.

Article required: headline, image, datePublished, author. Google wants author to be either a Person or Organization with a name and url — not just a text string.

Event required: name, startDate, location. The location needs to be a Place with an address, or a VirtualLocation with a url.

Product required: name, image, and either review, aggregateRating, or offers.

The most common audit finding we report is not missing schema — it's incomplete schema. Blocks that parse correctly but lack the properties Google actually needs to generate a rich result.

We wrote about implementing these schema types properly in our structured data guide for local businesses. That guide covers the full property list for each type with working code examples. This article is about what goes wrong after you think you've done it right.

One specific mistake keeps appearing in sites built with popular WordPress SEO plugins: the author field on Article schema set to a plain string instead of a structured object. This is valid schema.org syntax, but Google's rich results documentation explicitly wants a Person or Organization type with a name property. The difference between "author": "Breemedia" and "author": { "@type": "Organization", "name": "Breemedia", "url": "https://www.breemedia.com" } is the difference between eligible and not eligible.

Nesting Errors and Broken References

Schema markup works best as a connected graph of entities, not isolated fragments. That's what @id references are for — they let one schema block point to another, telling search engines "this Service is provided by this LocalBusiness at this Location." When those references break, Google sees disconnected data instead of a coherent picture of your business.

The most common nesting error we find: a LocalBusiness schema on the homepage defining @id: "https://example.com/#business", and then Service or Event schemas on subpages referencing @id: "https://example.com#business" (no trailing slash) or @id: "https://www.example.com/#business" (www vs non-www). These look almost identical to a human. To a JSON parser, they're completely different strings. The reference doesn't resolve and the connection is lost.

Another frequent problem: nesting an address inside a LocalBusiness without declaring its @type. This happens when developers hand-write JSON-LD instead of using a schema generator:

{
  "@type": "LocalBusiness",
  "name": "Mountain View Plumbing",
  "address": {
    "streetAddress": "1240 9th Avenue SE",
    "addressLocality": "Calgary",
    "addressRegion": "AB"
  }
}

That address object is missing "@type": "PostalAddress". Some validators won't flag it because schema.org's specification can infer the type from context. But Google's Rich Results Test will flag it, and more importantly, Google may not correctly parse the address fields without the explicit type declaration.

The same applies to openingHoursSpecification, geo, offers, and any other nested object. Always declare the @type on every nested entity. It costs you one extra line per object and removes all ambiguity.

A real-world example we fixed last year: A Calgary restaurant had Event schema for their weekly live music nights. The location property pointed to an @id reference for the restaurant's LocalBusiness schema. Good practice. Except the LocalBusiness schema was only present on the homepage, and the events page didn't include it. Google crawled the events page, found a reference to an entity that didn't exist on that page, and ignored the entire Event schema. The fix was adding the LocalBusiness schema to every page that referenced it — or embedding the location data directly in the Event schema rather than using an @id reference.

Content Mismatch: When Your Schema Lies

Google's structured data guidelines state it plainly: your markup must accurately represent the content visible on the page. This isn't a suggestion. Mismatched content between structured data and page content can result in a manual action penalty — Google's term for deliberately removing your rich results.

We see content mismatch in three forms:

Outdated information. Business hours change seasonally. Prices go up. Phone numbers get ported. But schema markup sits in a template file that nobody updates. A customer sees "Open until 8 PM" in Google's rich result, drives to the business at 7 PM, finds it closed. That customer doesn't come back. And if Google's systems detect the inconsistency between your schema and your visible page content, they'll stop displaying the rich result entirely.

Exaggerated claims. An aggregateRating of 4.9 with 200 reviews — but the business only has 40 reviews on their site, averaging 4.2. Google checks. They cross-reference your claimed review count against what they can verify on your page and through third-party sources. Inflating your rating in schema doesn't give you better star ratings in search results. It gets your star ratings removed.

Schema on the wrong page. Product schema on a category page that lists 50 products. FAQ schema on a page that doesn't actually display those questions and answers. Event schema for events that happened three months ago and were never removed. The rule is straightforward: the structured data on a page must describe content that exists on that page, is visible to users, and is current.

This connects directly to what we covered in our piece on getting recommended by AI search engines. AI assistants pull data from your structured markup and present it as fact. If that data is wrong, the AI confidently tells potential customers wrong information about your business. That's worse than not appearing at all.

Using the Wrong Schema Type (or a Deprecated One)

Schema.org has hundreds of types. LocalBusiness alone has over 100 subtypes. Using the generic type when a specific one exists means you're leaving context on the table. A dental practice should use Dentist, not LocalBusiness. A law firm should use LegalService. A restaurant should use Restaurant — which gives access to properties like menu, servesCuisine, and acceptsReservations that LocalBusiness doesn't support.

The reverse error is just as damaging: using a type that doesn't match your business at all. We've seen a web design agency marked up as a ProfessionalService with serviceType: "Medical" because someone copied a template and only changed the business name. Google's systems are sophisticated enough to detect when your schema type contradicts the actual content of your page.

And then there are deprecated types. Google announced in November 2025 that it would stop supporting several structured data types starting January 2026, including Practice Problem, Dataset (for Google Search — it remains for Dataset Search), and Sitelinks Search Box. If your site still carries markup for deprecated types, it won't cause ranking damage, but it's dead weight that clutters your code and makes debugging harder. Clean it out.

The schema.org vocabulary itself also evolves. Properties get deprecated and replaced. The priceRange property on LocalBusiness, for instance, is being discussed for deprecation in favour of more granular pricing structures. Checking the schema.org release notes once or twice a year keeps your markup current.

How to Find and Fix Your Errors

Two tools. Use both. They check different things.

Google's Rich Results Test (search.google.com/test/rich-results) tells you whether your structured data qualifies for Google's specific rich result features. It only validates schema types that Google supports for rich results — which is a subset of what schema.org defines. If your markup passes here, Google can generate enhanced search listings from it. If it shows errors, those specific issues are preventing your rich results from appearing.

The Schema Markup Validator (validator.schema.org) checks your markup against the full schema.org specification. It catches vocabulary errors, incorrect property types, and structural problems that the Rich Results Test might not flag. It validates all schema types, not just the ones Google uses for rich results.

Run both. The Rich Results Test might show your LocalBusiness schema as valid while the Schema Markup Validator flags that you've used a deprecated property or an incorrect value type. Conversely, schema that's technically correct per schema.org might fail the Rich Results Test because it's missing a property Google specifically requires for that feature.

Google Search Console is where you monitor ongoing issues. The Enhancements section shows structured data errors across your entire site, grouped by schema type. If you have a Product schema error on 200 pages because of a template issue, Search Console shows that as one issue affecting 200 pages — fix the template, fix all 200. The Unparsable Structured Data report catches syntax errors that prevent Google from even identifying what type of schema you were attempting.

The workflow that actually works:

  1. Run the Rich Results Test on every page template (not every individual page — templates share the same schema structure)
  2. Fix all errors (red). Review all warnings (yellow). Errors block rich results. Warnings mean you're missing recommended properties that would make your rich result more complete.
  3. Run the Schema Markup Validator on the same pages to catch anything the Rich Results Test missed
  4. Check Search Console's Enhancements reports weekly for the first month after making changes, then monthly
  5. Re-validate after every site update, theme change, or plugin update. We cannot stress this enough — we've seen WordPress theme updates silently overwrite custom schema with the theme's default (broken) markup.

For sites we build and maintain, validation is part of our standard development process. We run both tools during development, after launch, and after every significant site change.

Schema markup validation checklist:

  • Validate JSON syntax before anything else (use a JSON linter or VS Code)
  • Run every page template through Google's Rich Results Test — fix all errors
  • Run the same pages through the Schema Markup Validator — catch vocabulary issues
  • Confirm every nested object has an explicit @type declaration
  • Verify all @id references match exactly (protocol, www, trailing slashes)
  • Check that schema content matches visible page content — hours, prices, ratings, addresses
  • Use the most specific @type available for your business (not generic LocalBusiness if a subtype exists)
  • Remove markup for deprecated schema types (check Google Search Central announcements)
  • Monitor Search Console's Enhancements reports weekly after changes, monthly ongoing
  • Re-validate after every theme update, plugin update, or site migration
  • Keep openingHoursSpecification current — outdated hours in rich results actively drive customers away

The Patterns Behind the Mistakes

Most schema errors aren't random. They follow patterns tied to how the markup got there in the first place.

Theme-generated schema is the biggest source of broken markup on WordPress sites. We've audited themes that output WebSite schema listing the theme developer as the author, Organization schema with the demo site's address still hardcoded, and LocalBusiness schema that conflicted with the site owner's manually-added markup — producing duplicate, contradictory blocks that Google couldn't reconcile. If you use a WordPress theme, check what it auto-generates before adding your own schema. Duplicating a schema type causes conflicts. Use a tool like Google's Rich Results Test on a live page to see exactly what's there.

Plugin-stacked schema is the second pattern. Yoast adds some schema. Rank Math adds more. A dedicated schema plugin adds a third layer. Each plugin assumes it's the only one generating structured data. The result is three Organization blocks, two WebSite blocks, and a tangle of @id references pointing at different entity definitions for the same business. Pick one tool to manage your schema and disable structured data output from the others.

Copy-paste templates are what the plumbing company at the start of this article got. Someone finds a schema example online, changes the business name and address, and pastes it into the site. They don't change the @type from the example's Restaurant to Plumber. They leave the example's timezone offset in the openingHoursSpecification. They forget to update the @context from the example's http:// to https://. The markup looks complete at a glance. It fails on validation.

Your site's performance in Core Web Vitals affects how quickly Google crawls and indexes your structured data. A slow site gets crawled less frequently, which means schema fixes take longer to be picked up. Speed and structured data aren't separate problems.

Structured data isn't a set-it-and-forget-it task. It's a living part of your site that needs the same maintenance as your content, your security certificates, and your business hours. Validate it regularly, update it when your business changes, and treat every error as a lost opportunity for a rich result that would have sent a customer your way.


Sources

Get In Touch

Let's talk about your project.

Whether you have a clear scope or just a rough idea, we'd love to hear from you. Tell us what you need and we'll get back within one to two business days.

Not sure where to start? Take our 2-minute assessment and get a personalized recommendation before reaching out.

Rather see our thinking first? Include your current website in the form and we’ll review it before we reply — your response comes back with the three highest-impact things we’d fix, not a sales pitch. If you’d like to walk through them together after, we’re happy to.

Calgary, Alberta, Canada

Response within 1–2 business days

Tell us about your project

The more detail you share, the better we can understand how to help.