Skip to content

How to validate structured data (and what a green tick really proves)

Technical · 8 min read · Updated 2026-11-13

Short answer: To validate structured data, test the live rendered page, not your template, with Google's Rich Results Test for Google features and the Schema Markup Validator for general schema.org syntax, then count the JSON-LD blocks and parse each one yourself.

Most errors come from a few mechanical causes: invalid JSON, a missing required property, two plugins emitting overlapping blocks, or colliding @id values. A clean result proves the markup parses and declares what it must. It does not prove the markup matches the page, which no validator can check.

What are you actually validating?

Validation answers two different questions, and mixing them up is why people misread results. First: is there any structured data at all? Second: is what exists well formed enough to be used? A site can pass the first and fail the second, and the reverse is not possible.

1 invalid item

In the AEO Toolkit's validator, a JSON-LD block that does not parse is counted as one invalid item. So a page with only broken markup shows present: pass and valid: fail, and the pass does not mean the markup works. (AEO Toolkit skill: structured data validation)

Broken markup is ignored by whatever reads it, which is worse than none, because the page looks covered. That is the real reason to validate: not to collect a green tick, but to find the block that is silently doing nothing.

Which tools should you use, and what does each one miss?

ToolGood forBlind spot
Rich Results TestTesting a URL or pasted code with Googlebot and seeing which Google rich results it is eligible forOnly knows Google's supported features. A deprecated type can show nothing for perfect markup.
Schema Markup ValidatorA generic schema.org syntax and vocabulary check, independent of Google featuresDoes not tell you whether Google will use it for anything.
A parsing scriptSeeing exactly what a crawler extracts from the served HTML, including blocks that fail to parseChecks syntax and declared requirements, not truth.
view-source plus a JSON parserFinding every block and where it came fromManual, so it does not scale past a few templates.

Do not read no rich results detected as a markup bug

Several Google rich result types have been deprecated, so a clean Rich Results Test may list no eligible features even when the markup is perfect. FAQ is the clearest example. Check the type before you hunt for an error.

How do you validate a page, step by step?

  1. Test one URL per template

    Home, article, product and any FAQ page each need a check. Test the live URL, because the live page can carry extra blocks that a pasted snippet does not.

  2. Fetch it the way a crawler does

    Request the served HTML with no JavaScript. If the markup only appears after scripts run, a crawler reading raw HTML may not see it even if Google's renderer does.

  3. Count the blocks

    Search for application/ld+json in the output and count them. The number should equal what you intend. An unexpected extra block is usually a plugin or theme.

  4. Parse each block

    Run every block through a JSON parser. A parse failure points at the exact position of the error, such as a stray comma or an unescaped quote.

  5. Run both external validators

    Use the Rich Results Test and the Schema Markup Validator. You want zero errors. Read warnings and decide, because missing recommended properties are not errors.

  6. Compare the markup to the visible page

    Check headline, byline, dates, price and answers against what a visitor sees. Any mismatch is a defect even if every validator is happy.

There is a full walk-through, with a runnable parsing script and fixes organised by cause, in the implementation guide for the agent skill. The skill can be installed into Claude Code and other coding agents so an agent runs the checks against your site and proposes the fixes.

Read the full implementation guide

The skill source, including the validation rules it applies, is public.

View the skill source on GitHub

To install any of the AEO skills into an agent, start from the index.

See how to install AEO agent skills

What causes the errors, and how do you fix each one?

  • Invalid JSON: Find the block, run it through a JSON parser, and fix the reported position. Generate JSON-LD from an object with the language's encoder, never by gluing strings together.
  • HTML entities inside the script: A script body is not HTML-decoded, so an ampersand entity appears literally in your strings. Write the real character. Escape the less-than sign when content is user-controlled so a closing script tag in a string cannot break out.
  • A missing required property: Output it from real data, or omit the whole node when the data does not exist. Do not emit empty strings to quiet a warning.
  • Duplicate and conflicting blocks: Identify every source with view-source, keep one emitter per entity type, and disable the others rather than hand-merging. Identical duplicates are harmless but wasteful. Differing ones are the defect.
  • @id collisions: Two different things sharing an @id are ambiguous, for example the WebPage and the Organization both using the homepage URL. Use distinct fragments such as /#organization, /#website and /page#article.
  • Wrong value types: Dates in ISO 8601, url and image as absolute URLs, and sameAs as an array of URL strings.

Two further notes. Google supports JSON-LD, Microdata and RDFa equally when they are valid and recommends JSON-LD where your setup allows, so do not convert working Microdata for its own sake. And mixing JSON-LD and Microdata for the same entity is where duplicates and conflicts usually start.

What does a passing result not tell you?

Passing is a low bar. The AEO Toolkit audit checks a short list of required properties on a short list of types, and its lists are its own: Organization and Person need a name, Article, NewsArticle and BlogPosting need a headline, and so on. Any other type is treated as valid without checks, so valid there means no defined rule was broken, not that the markup is complete.

  • Only top-level items are checked: A Person nested inside an author field counts toward presence but is not itself checked for a name.
  • Property names are matched case-insensitively: That is more lenient than schema.org and Google, so a wrongly capitalised property can pass the toolkit and still be ignored elsewhere.
  • Google's required lists differ from the toolkit's: Google's Article documentation lists no required properties, while the toolkit requires a headline. When they disagree, satisfy both.
  • Several things are never detected: Duplicate blocks, @id collisions, references that point nowhere, wrong value types, and markup that contradicts the page all slip through.

Valid is not the same as true

Google's guidelines forbid markup that does not match the visible content, and no validator detects that. Do not fix warnings by adding invented data, and do not chase recommended properties for their own sake. Fewer, complete and accurate properties beat many badly formed ones.

What about caching and staging after you fix it?

Three pitfalls catch people after the markup is right. Test the rendered HTML, not the source file, because a template can look correct and output something different. A CDN or page cache can keep serving the old markup after you fix it, so confirm the live response changed. And if your @id and url values are generated from the request host, a preview or staging domain can publish its own address as your identity.

Once deployed, check Search Console reports for the same URL if you have access. Allow time for Google to recrawl: days to weeks, not the same afternoon.

Common questions

What is the best tool to validate structured data?

Use two. Google's Rich Results Test tells you which Google rich results a URL is eligible for, and it only knows Google's supported features. The Schema Markup Validator checks generic schema.org syntax and vocabulary regardless of Google features. Add a parser or script on the served HTML to see exactly what a crawler extracts.

Why does my structured data pass but show no rich results?

Because validity and eligibility are different questions. Several Google rich result types have been deprecated, so perfect markup can show no eligible features. Also, markup makes a page eligible for a feature, it does not guarantee one. Check whether the type still has a Google feature before treating the result as a bug.

How do I fix duplicate schema from Yoast or Rank Math?

Find every source of JSON-LD in the rendered HTML, note which blocks come from the theme and which from plugins, keep one emitter per entity type, and disable the others in their settings. Do not hand-merge. If the duplicate nodes are identical they are wasteful but harmless. If they differ, such as two Organizations with different ids, that is the defect.

Does valid structured data mean my markup is correct?

No. A validator checks that markup parses and declares its required properties. It cannot check that the markup matches the visible page, which Google's guidelines require. Compare headline, dates, price and answers against what a visitor sees, and treat any mismatch as a defect even when every tool shows a pass.

Sources

Related guides

Want it done for you

Want this done and re-checked every month? Our monthly maintenance re-runs your buying questions in ChatGPT, Perplexity and Google, ships the fixes that keep you out of the answers, and reports what moved. Or run the free check on your site first at advancelabs.dev/tools/audit.

See how it works

Book a 30-minute call