Technical SEO

The JSON-LD mistakes that silently kill your rich results

TS Talha Shahzad··7 min read
The short version
  • Schema validators only check syntax, not whether Google will actually use the markup.
  • Duplicate Organization entities and conflicting property values are the most common silent killers.
  • Broken @id references create disconnected nodes that Google can't resolve into a coherent graph.
  • Empty required fields pass validation but get quietly skipped by Google's systems.
  • A 10-minute manual audit catches the structural problems that automated tools miss.

Your JSON-LD passes every validator you throw at it. Green checkmarks across the board. But when you check Google Search Console, nothing. No rich results, no enhancements, no sign that Google even noticed the markup.

This is the most frustrating kind of technical SEO problem because there's no error message to chase. The code is valid. Google just decided to ignore it. After auditing schema across dozens of client websites, I can tell you the cause is almost always the same handful of structural mistakes that validators aren't designed to catch.

Validators check syntax, not logic

Here's the thing most developers don't realize about Google's Rich Results Test and Schema.org validators: they check whether your JSON-LD is well-formed. They confirm the syntax is correct, the types exist, and the properties match. What they don't check is whether the markup makes sense as a whole.

Think of it like spell-check on a contract. Every word is spelled correctly, but the contract contradicts itself in three places and references a clause that doesn't exist. Spell-check passes. The contract is still broken.

That gap between "valid code" and "useful code" is where rich results go to die. Google's systems need to build a coherent knowledge graph from your markup. If the pieces conflict with each other, Google doesn't throw an error. It just moves on.

Duplicate Organization entities confuse Google

This is the single most common problem I find. A site has two, sometimes three, separate Organization entities scattered across its pages.

How it happens: the developer adds an Organization block to the site header template. Then a WordPress SEO plugin injects its own Organization block. Then someone manually adds another one on the About page. Each block defines the same company but with slightly different details: a different logo URL here, a slightly different business name there, an extra social profile link on one but not the others.

Google now sees three "sources of truth" for who this organization is. None of them match exactly. So Google trusts none of them.

The fix is straightforward. Define your Organization exactly once, give it a clear @id (like https://yoursite.com/#organization), and have every other reference point back to that single @id. One source of truth, many references. That's how schema is supposed to work.

Conflicting property values across blocks

Even without outright duplication, conflicting values between related schema blocks will quietly break things.

I've seen a site where the LocalBusiness schema listed the business hours as 9 to 5, Monday through Friday. The OpeningHoursSpecification on the Contact page said 8 to 6. The Google Business Profile said 9 to 6. Three different answers to the same question.

Google's response to conflicting signals is predictable: distrust. If your own site can't agree on your business hours, why should Google confidently display them in a rich result?

This extends to everything: phone numbers, addresses, URLs, price ranges, review counts. Every property that appears in more than one schema block needs to match exactly. Not "close enough." Exactly.

Run a simple grep across your codebase for key properties like telephone, address, openingHours, and priceRange. If the same property appears with different values in different blocks, you've found your problem.

Broken @id references don't resolve

The @id property is how JSON-LD creates internal links between entities. Your WebPage references your Organization. Your Article references its author. Your BreadcrumbList references its parent pages.

When an @id reference points to an entity that doesn't exist, or that exists with a different @id than expected, the reference breaks silently. The validator doesn't flag it because the syntax is fine. But Google can't follow the link, so it treats the entities as disconnected fragments instead of a coherent graph.

Here's a real example. A site's Article schema referenced the author with "author": {"@id": "https://example.com/#author-john"}. But the Person entity on the team page used "@id": "https://example.com/team/john". Two different identifiers for the same person. The reference never resolves.

The discipline here is simple but requires attention: every @id you reference must match an @id you define somewhere else on the site, character for character. I keep a spreadsheet of all @id values for any site with more than a handful of schema types. It sounds tedious. It prevents exactly this class of bug.

Want a website that turns visitors into customers, not just compliments?

Book a 15-min intro

Empty required fields fail quietly

Schema.org marks certain properties as "expected" or "required" for specific rich result types. Google's documentation goes further, specifying which fields are required versus recommended for each rich result type.

When a required field is present but empty, validators sometimes pass it because the property exists. Google's systems see an empty value and skip the entire entity.

The usual culprits:

  • An image property that points to an empty string or a broken URL.
  • A datePublished field set to an empty string instead of an ISO 8601 date.
  • A name property left as placeholder text like "Your Business Name Here."
  • An author object with a name property that's an empty string.

These are easy to spot once you know to look for them. Open your page source, find the JSON-LD block, and read every value. If any value is empty, placeholder text, or a URL that 404s, fix it.

Too many schema types with too little substance

There's a temptation, especially with plugins that auto-generate schema, to mark up everything. Every page gets Article, Organization, BreadcrumbList, WebSite, WebPage, and sometimes FAQPage and HowTo thrown in for good measure.

More schema types are not better. Each type you add is a commitment to provide complete, accurate, consistent data for that type. If your FAQPage schema contains one question with a two-word answer, Google isn't going to reward that with a rich result. If your HowTo schema has steps like "Step 1: Get started," you're wasting markup.

Only implement schema types where you have genuine, complete content to back them up. A clean implementation of two types beats a sloppy implementation of eight.

The 10-minute manual check that catches what validators miss

Here's the audit I run on every client site before I consider the schema done. It takes about ten minutes and catches problems that no automated tool will flag.

  1. Count your entities. Search the entire codebase for @type. List every unique entity type and count how many times each appears. If Organization appears more than once, that's your first fix.

  2. Map your @id references. List every @id you define and every @id you reference. Make sure every reference has a matching definition. If something is referenced but never defined, the link is broken.

  3. Check value consistency. Pick five key properties: business name, phone number, address, URL, and logo. Search for each one across all schema blocks. If any value differs between blocks, reconcile them.

  4. Read every value. Open the rendered JSON-LD on three to five key pages. Read each property value. Flag anything empty, placeholder, or obviously wrong.

  5. Test in Google's Rich Results Test. Not just for green checkmarks, but read the parsed output. Does the preview match what you expect? If it looks wrong in the preview, it'll look wrong in search results.

  6. Cross-reference with Search Console. Go to the Enhancements section. If Google has found problems with your schema, they'll show up here, sometimes weeks after deployment.

This manual pass is not glamorous work. It's the kind of thing that's easy to skip when a validator already gave you the green light. But it's the difference between schema that validates and schema that actually earns rich results.

Why this matters for your business

Rich results aren't just vanity metrics. A proper rich result can double the visual footprint of your listing in search results. Review stars in a product listing measurably increase click-through rates. Event schema gets your events into Google's event carousel.

When these features work, they compound. When they silently fail, your business loses out on high-intent search traffic because searchers pass over your listing for a competitor's richer, more detailed snippet.

The irony is that the fixes are usually small. Twenty minutes of cleanup, not a complete rebuild. The hard part is knowing where to look, because the automated tools won't tell you.

So before you assume your schema is working because a validator passed it, pull up your JSON-LD, read it like a human, and ask whether it tells a coherent, consistent story about your business. If it doesn't, Google noticed before you did. That's why your rich results aren't showing.

Prefer to hire through Upwork?
Top Rated Plus, 100% Job Success, 450+ projects shipped. See the reviews and start a contract.
Hire me on Upwork

FAQ

Why does my schema pass validation but not generate rich results?

Validators check syntax, not logic. Your JSON-LD can be perfectly structured but still confuse Google if it contains duplicate entities, conflicting values, or broken internal references. Google needs a clean, unambiguous graph to generate rich results.

How do I find duplicate Organization entities across my site?

Search your codebase for every instance of @type: Organization. Most sites have one in the header template, another injected by a plugin, and sometimes a third on the About page. Each one should share the same @id, or better yet, only one should exist and the others should reference it.

Does Google penalize bad schema markup?

Not as a ranking penalty, but Google will silently ignore markup it can't trust. Spammy or inaccurate schema can also trigger a manual action that removes all rich results from your site. The practical effect is the same: you lose the visibility you were trying to gain.

All posts
the next step is small

Want a site that does this for you?

15 minutes, no deck, no pressure. Worst case, you leave with a free plan.

keep reading

More notes