Technical SEO
Schema Markup Validators Compared: Rich Results Test vs Schema.org Validator vs the Rest
A schema markup validator is a tool that parses the structured data on a page and reports whether it is well-formed, uses real schema.org types and properties, and (for Google’s own tool) meets the requirements for a rich result. No single validator checks all three, and the gaps between them are where broken markup reaches production.
To show where those gaps sit, I wrote five JSON-LD blocks, each broken in a different way, and ran all five through six validators: the Schema Markup Validator, three open-source libraries, a TypeScript type check and a plain JSON parser. This article reports what each tool caught and missed, explains where Google’s Rich Results Test fits, and ends with a command-line setup that fails a build before bad markup ships.
Key takeaways
- The JSON syntax error was the only break that most tools caught. The block whose markup described a rating the page never shows passed all six.
- The Schema Markup Validator checks vocabulary, not Google eligibility. It flagged the syntax error and the misspelt property, and returned zero errors for a
$in the price and for a Product that Google would reject. - The Rich Results Test is the only tool that knows Google’s current rules, but it has no API, so it cannot sit in a build pipeline.
- For CI, Adobe’s open-source
@adobe/structured-data-validatorcaught four of the five breaks in this test, but it reports an unknown property as a warning, so you have to promote that warning to a failure yourself. - No automated tool checks that the markup matches what a visitor can see. That remains a review step.
The two official tools, and what each is for
Google’s own guidance splits the job in two. Its structured data testing page says to start with the Rich Results Test “to see what Google rich results can be generated for your page”, and to use the Schema Markup Validator “to test all types of schema.org markup, without Google-specific validation”.
That split dates from 2020. Google’s update on the Structured Data Testing Tool announced that the old tool would move to a schema.org domain, check “syntax and compliance of markup with schema.org standards”, and “no longer check for Google Search rich result types”. An August 2021 note on the same post says the old tool now redirects to a landing page that helps you pick between the two.
So the two tools answer different questions:
| Rich Results Test | Schema Markup Validator | |
|---|---|---|
| Question it answers | Can this page get a Google rich result? | Is this valid schema.org markup? |
| Types covered | Only the rich result types Google supports | Every schema.org type |
| Knows Google’s required properties | Yes | No |
| API for automation | None | None documented |
The Rich Results Test
The Rich Results Test is the only tool that applies Google’s feature rules. Its help page says it accepts a URL or a pasted code snippet, supports JSON-LD, RDFa and Microdata, and lists the rich result types it currently supports, from Article and Breadcrumb to Product snippet, Merchant listings, Review snippet and Video.
FAQ is not on that list any more. Google stopped showing FAQ rich results from 7 May 2026, posted the deprecation notice on 8 May, removed the documentation on 15 June 2026 and dropped Rich Results Test support in June 2026 (Google Search Central changelog). This is distinct from the August 2023 restriction, which narrowed FAQ rich results to government and health sites rather than removing them. A FAQPage block can still be valid schema.org, and the Schema Markup Validator will still check it, but the Rich Results Test will not.
Two details from Google’s documentation matter for anyone relying on it. URL mode fetches the page as Google-InspectionTool, so a page blocked by robots.txt cannot be tested. And the tool ignores comments inside JSON-LD, which the help page warns “is not supported by the JSON-LD standard and so might result in errors in actual usage”.
The Schema Markup Validator
The Schema Markup Validator validates “all Schema.org-based structured data that’s embedded in web pages, without Google feature specific warnings”, in Google’s words. It is the right tool when you use a type Google does not consume, when you want to confirm property names are real, or when you are marking up for consumers other than Google Search, such as the AI assistants covered in structured data for AI search.
It does not know that Google requires offers, review or aggregateRating on a Product snippet, and it does not know which types Google has retired. A clean result from it means the vocabulary is correct, not that the page is eligible for anything.
The test: five JSON-LD blocks, each broken a different way
Each block sits in a minimal HTML page whose visible text matches the markup, except where the break is about visible content. Four of the breaks are common template mistakes; the fifth is the one no tool is built to find.
Block A, syntax. A BlogPosting with a trailing comma after the last property. JSON does not allow it.
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Schema markup validators compared",
"datePublished": "2026-10-22",
"author": { "@type": "Person", "name": "Nadia Mohamed" },
}
Block B, vocabulary. The same BlogPosting with datePublished misspelt as datePublised. The JSON is valid; the property does not exist.
Block C, value format. A Product whose offers.price is "$49.00". The schema.org definition of price says to use priceCurrency “instead of including ambiguous symbols such as ’$’ in the value”, and Google’s product snippet documentation types price as a Number.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Technical SEO audit template",
"image": "https://example.com/audit-template.png",
"offers": {
"@type": "Offer",
"price": "$49.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
}
}
Block D, Google requirement. A Product with a name, image and description but no offers, review or aggregateRating. That is valid schema.org, but the same Google page says product snippets require one of those three.
Block E, invisible content. A correct Product with a correct Offer, plus an aggregateRating of 4.8 from 212 reviews that appears nowhere on the page. Google’s general structured data guidelines say: “Don’t mark up content that is not visible to readers of the page.”
I also ran a control: Block E without the rating, with the price written as "49.00". Every tool passed it.
Results: what each validator caught
The runs used the Schema Markup Validator on 24 September 2026, @adobe/structured-data-validator 1.7.0 against the schema.org 30.1 vocabulary, structured-data-testing-tool 4.5.0 with its Google preset, jsonld 9.0.0, schema-dts 2.0.0 with TypeScript 7.0.2, and Node’s JSON.parse.
| Block | JSON.parse | jsonld.js | schema-dts + tsc | Schema Markup Validator | Adobe validator | sdtt (Google preset) |
|---|---|---|---|---|---|---|
| A: trailing comma | Caught | Caught (parse fails) | Missed | Caught | Caught | Logged, exit code 0 |
| B: misspelt property | Missed | Missed | Caught | Caught | Warning only | Indirectly |
C: $ in price | Missed | Missed | Missed | Missed | Caught | Missed |
| D: no offers, review or rating | Missed | Missed | Missed | Missed | Caught | Missed |
| E: rating not on page | Missed | Missed | Missed | Missed | Missed | Missed |
Here is what sits behind each cell.
Block A: the one everything catches, almost
The Schema Markup Validator returned a single severe error, JSON_PARSE_ERROR. Adobe’s validator returned “Could not parse JSON-LD”. JSON.parse threw, so jsonld.js never saw the document.
Two results are worth knowing. structured-data-testing-tool printed the parse error, reported “No tests run” and exited with code 0, so a CI job that trusts its exit code would pass a page whose only structured data is broken.
The TypeScript check passed Block A, and that is not a bug. A trailing comma is legal in a TypeScript object literal, and JSON.stringify will never emit one. If you generate JSON-LD from typed objects rather than writing it as text, this whole class of error cannot reach the page.
Block B: the typo that plain JSON-LD tooling accepts
The Schema Markup Validator flagged datePublised as INVALID_PREDICATE for BlogPosting. The TypeScript compiler rejected it with error TS2353 (“Object literal may only specify known properties”). Adobe’s validator reported it as a warning: “Property “datePublised” for type “BlogPosting” is not supported by the schema.org specification”.
jsonld.js expanded the block without complaint, even in its safe mode. That is correct behaviour for a JSON-LD processor, because the schema.org context maps any unknown term onto the schema.org namespace. A JSON-LD library tells you the document is well-formed linked data, not that the terms mean anything.
structured-data-testing-tool did not name the typo, but its Google preset failed the block for a missing datePublished, which points you to it. The same preset also failed the block for missing image and publisher fields, which Google does not require: its Article documentation says “There are no required properties” and lists author, dateModified, datePublished, headline and image as recommended. Its latest version, 4.5.0, was published in March 2020, and its Google preset covers only the Article family, ClaimReview and Organization.
The Rich Results Test is unlikely to help here either. Google’s Article page notes that the Rich Results Test “doesn’t show a warning” for a missing datePublished, because the property is only recommended.
Block C: a format error that looks fine to a vocabulary checker
Only Adobe’s validator caught the dollar sign, as an error on the price type. The Schema Markup Validator returned zero errors and zero warnings, and listed the price as $49.00.
This is the gap between the two jobs. On schema.org, price accepts Number or Text, so "$49.00" is valid vocabulary, and the currency-symbol rule sits in the usage guidelines rather than the type. Google’s documentation expects a number. The Rich Results Test help page lists “Invalid number” among the errors it can report; I did not run this block through it, so I cannot tell you whether it raises that error here.
Block D: valid schema.org, ineligible for Google
Adobe’s validator returned “One of the following attributes is required: “aggregateRating”, “offers” or “review"", matching Google’s product snippet requirement word for word. The Schema Markup Validator, sdtt and the type check all passed it.
This is the most common way a site ends up with markup that validates and never produces a rich result. Google’s own general guidelines are blunt about it: “Items that are missing required properties are not eligible for rich results.” The Rich Results Test exists to catch exactly this.
Block E: the break no validator can see
Every tool passed Block E. Adobe’s validator returned one warning about a missing product identifier (a gtin or isbn) and 17 optional-field suggestions, none of which mentioned the rating.
This is by design, not a weakness in any one tool. Google’s guidelines separate technical guidelines, which it says the Rich Results Test and URL Inspection tool “catch most” of, from quality guidelines, which “are not easily testable using an automated tool”. Its Article documentation adds that when the problem is spammy content or markup, “the issue may not be a syntax issue, and so the Rich Results Test won’t be able to identify these issues.”
The consequence is not a validation error but a manual action, which Google says removes the page’s eligibility for rich results without affecting how it ranks. If your markup is generated from a database, compare the rendered page with the JSON-LD for every template, not just the first one.
The rest: other validators you will come across
The six tools above are the ones I could run and report honestly. Most other options fall into one of three groups.
- Web checkers and browser extensions. The rest of the first page of results for “schema markup validator” is mostly free web tools and Chrome extensions. Most run in the browser and wrap schema.org parsing with their own rules. They are useful for a quick look, but check which vocabulary version and which Google rules a tool claims to apply before you trust a pass.
- Site crawlers. Desktop and cloud crawlers can extract and validate structured data across a whole site. That is the right level for an audit, because template bugs show up as patterns. The crawler options are covered in the best technical SEO tools.
- Search Console reports. After deployment, the rich result status reports and the Unparsable structured data report show errors Google found while crawling. They catch what reached production, which is exactly why they cannot be your only check.
Validating in CI: the command-line and API options
The Rich Results Test has no API, and the Schema Markup Validator has no documented one. (The validator’s web page posts to an endpoint that returns JSON, which is how I ran these blocks, but an undocumented endpoint is not something to build a release gate on.) For automation you need a library, or Google’s data about pages it has already indexed.
Option 1: a library-based gate on your build output
Adobe’s structured-data-validator describes itself as validating structured data “according to Schema.org specifications and Google Rich Results requirements”. It pairs with @marbec/web-auto-extractor, which pulls JSON-LD, Microdata and RDFa out of HTML. In this test it was the only tool to catch Blocks C and D.
It needs a copy of the schema.org vocabulary. Pin a release rather than fetching “latest” on every run, so a vocabulary change cannot fail a build that changed nothing. Releases are published in the schemaorg repository.
npm install --save-dev @adobe/structured-data-validator @marbec/web-auto-extractor
curl -sSfo schemaorg-all-https.jsonld \
https://raw.githubusercontent.com/schemaorg/schemaorg/main/data/releases/30.1/schemaorg-all-https.jsonld
This script walks a build directory, validates every HTML file and exits with code 1 on any error. It also promotes the unknown-property warning to a failure, because otherwise Block B passes.
// scripts/validate-structured-data.mjs
// Usage: node scripts/validate-structured-data.mjs dist
import fs from 'node:fs';
import path from 'node:path';
import Validator from '@adobe/structured-data-validator';
import WebAutoExtractor from '@marbec/web-auto-extractor';
const root = process.argv[2] ?? 'dist';
const schema = JSON.parse(fs.readFileSync('schemaorg-all-https.jsonld', 'utf8'));
const validator = new Validator(schema);
const extractor = new WebAutoExtractor({ addLocation: true, embedSource: ['rdfa', 'microdata'] });
const walk = (dir) => fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) =>
e.isDirectory() ? walk(path.join(dir, e.name)) : e.name.endsWith('.html') ? [path.join(dir, e.name)] : []);
let failed = 0;
for (const file of walk(root)) {
const html = fs.readFileSync(file, 'utf8');
const issues = await validator.validate(extractor.parse(html));
const errors = issues.filter((i) =>
i.severity === 'ERROR' || /not supported by the schema\.org specification/.test(i.issueMessage));
if (errors.length) {
failed++;
for (const e of errors) console.error(`${file}: ${e.issueMessage}`);
}
}
console.log(`${failed} page(s) with structured data errors`);
process.exit(failed ? 1 : 0);
Run against the five test pages plus the control, it printed errors for A, B, C and D, reported “4 page(s) with structured data errors” and exited with code 1. Run against the control alone, it exited with code 0.
A GitHub Actions job that runs it after the build:
name: structured-data
on: [pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm run build
- run: curl -sSfo schemaorg-all-https.jsonld https://raw.githubusercontent.com/schemaorg/schemaorg/main/data/releases/30.1/schemaorg-all-https.jsonld
- run: node scripts/validate-structured-data.mjs dist
Two limits apply. The library covers the types it has handlers for (Product, Offer, Review, Recipe, JobPosting, VideoObject, BreadcrumbList and a couple of dozen more), and it had no Article-specific rules in the version tested. And it reads the HTML you give it, so for client-rendered markup you need to validate rendered output, not the server response. The rendering side is covered in JavaScript SEO.
Option 2: type-check the markup where you write it
If your JSON-LD comes from TypeScript, Google’s schema-dts package gives you schema.org types. It caught the Block B typo at compile time, and building objects instead of strings rules out Block A entirely. It does not know Google’s required properties, so it complements a validator rather than replacing one.
import type { WithContext, Product } from 'schema-dts';
export const productLd: WithContext<Product> = {
'@context': 'https://schema.org',
'@type': 'Product',
name: 'Technical SEO audit template',
offers: { '@type': 'Offer', price: '49.00', priceCurrency: 'USD' },
};
Option 3: Google’s view of indexed pages, through the URL Inspection API
The Search Console URL Inspection API returns a richResultsResult with the detected rich result types, each item’s issues and an overall verdict. It has two limits for CI use. It reports “only the status of the version in the Google index”, so it cannot test a preview deploy. And its usage limits allow 2,000 inspections per day and 600 per minute per site.
That makes it a monitoring tool for important templates after release, not a pre-merge gate. Setting up access is covered in the Search Console API guide, and it fits the scheduled checks in SEO automation. For other SEO data sources you can call from the same pipeline, see the best SEO APIs.
Which validator to use, and when
Use them in layers, because each one covers a different failure.
- While writing: type the markup (schema-dts) or at least parse it. Block A should never reach a pull request.
- On every build: run a library validator over the built HTML and fail the job on errors and unknown properties. That catches Blocks A to D.
- Before launching a new template: paste the rendered HTML into the Rich Results Test, and run the live URL through it once the page is up. It is the only tool that applies Google’s current rules, including which types it no longer supports.
- For types Google does not use: check them in the Schema Markup Validator.
- In review: compare what the markup claims with what the page shows. Nothing automated does this.
- After release: watch the Search Console reports, and inspect key URLs through the API.
If you need working blocks to start from, the schema markup examples and the rich snippets JSON-LD guide have them. Validation is also one step in the technical SEO audit checklist. And if you are deciding whether rich results are worth this effort, do rich snippets help SEO covers that question.
If you want structured data validation built into your release process rather than run by hand, that is part of my technical SEO and GEO work.
Frequently asked questions
What is the best schema markup validator?
There is no single best one, because the tools check different things. Use the Rich Results Test for Google eligibility, the Schema Markup Validator for schema.org vocabulary, and a library such as Adobe’s structured-data-validator to check every page automatically in CI.
Is the Schema Markup Validator the same as Google’s Structured Data Testing Tool?
It is its successor. Google announced in December 2020 that the Structured Data Testing Tool would move to a schema.org domain and stop checking Google rich result types, and the old address now redirects to a landing page that helps you pick the right tool.
Why does my markup pass the Schema Markup Validator but fail the Rich Results Test?
Because the Schema Markup Validator only checks that you used real schema.org types and properties. It does not know Google’s required properties. In this test, a Product with no offers, review or aggregateRating returned zero errors in the Schema Markup Validator, while Google’s documentation says product snippets require one of the three.
Can I run the Rich Results Test from the command line or an API?
No. Google does not offer an API for it. The closest programmatic option is the Search Console URL Inspection API, which reports rich result issues for the version of a URL in Google’s index, but it cannot test unpublished code and is limited to 2,000 inspections per day per site.
Does valid schema markup guarantee a rich result?
No. Valid markup makes a page eligible, not entitled. Google can still decline to show a rich result, it no longer shows some types at all (FAQ is the most recent), and markup that describes content visitors cannot see can lead to a manual action that removes rich result eligibility.
Can a validator check FAQPage markup now that FAQ rich results are gone?
The Schema Markup Validator still checks FAQPage as schema.org vocabulary, which is useful if other consumers read it. The Rich Results Test no longer supports it, so a pass or fail there tells you nothing about FAQ markup.