Fixing Invalid JSON-LD Structured Data That Google Silently Ignores
A JSON-LD block sits right there in the page source, referencing the correct schema type, yet Search Console reports no structured data and rich results never appear. The markup isn't being penalized or deprioritized — it's being silently discarded, because a single syntax slip anywhere in the block is enough for the whole thing to fail to parse.
The Problem
A page has a <script type="application/ld+json"> block referencing a schema type like Article, Product, or FAQPage, added specifically to earn a rich result in search — a star rating, an FAQ dropdown, a recipe card. The markup is visibly present in the page's HTML source. Yet Google Search Console's structured data reports show zero detected items for that page, the Rich Results Test finds nothing, and the corresponding rich snippet never appears in actual search results, despite the page being indexed normally otherwise.
Why It Happens
JSON-LD is parsed as strict JSON — one syntax error discards the entire block, not just the broken field
Unlike HTML, which browsers parse leniently and recover from malformed tags, JSON has no such tolerance: a trailing comma, an unescaped quotation mark inside a string value, a missing closing brace, or a stray comment (JSON doesn't support comments at all) causes the entire JSON.parse call to fail. Google's structured data parser behaves the same way — it doesn't salvage the valid parts of a broken block, it discards the whole thing, which is why the page can look completely unmarked to Google despite the script tag clearly being present in the source.
The JSON-LD is injected by client-side JavaScript after the point Google's renderer captures the page
If structured data is added to the DOM via a client-side script running after initial render — common in single-page apps that build the <head> content dynamically — there's a timing dependency between when that script runs and when Google's crawler renders and captures the page's DOM. When that timing doesn't line up reliably, the JSON-LD is genuinely present in the running browser but effectively invisible to indexing, since search engines don't guarantee waiting for every possible async update before capturing rendered content.
The JSON is syntactically valid but missing required properties for that specific schema type
A JSON-LD block can parse successfully as JSON while still failing to qualify for a rich result, because different schema types (Product, Recipe, Article, etc.) each have their own required and recommended properties defined by Google's specific rich-result guidelines, separate from schema.org's more permissive general vocabulary. Missing a required field like offers on a Product or headline on an Article doesn't produce a parse error at all — it just quietly disqualifies the page from that particular rich result type.
The Fix
1. Validate the deployed page directly with Google's own tools, not just a manual read of the code
Run the actual live URL through Google's Rich Results Test and the Schema.org Validator rather than eyeballing the JSON for correctness — both tools parse the markup the same way Google's indexing pipeline does, and will surface a syntax error or a missing required field immediately, in a way that a visual code review reliably misses (a misplaced comma is easy to skim past).
2. Lint the JSON-LD as part of the build so a syntax error never reaches production
// build-time check, e.g. in a Node script or test
function assertValidJsonLd(jsonLdString) {
try {
JSON.parse(jsonLdString);
} catch (err) {
throw new Error(`Invalid JSON-LD: ${err.message}`);
}
}
A build-time JSON.parse check on every generated JSON-LD block turns a silent, hard-to-notice production failure into an immediate build failure — catching a trailing comma or an unescaped character before it ever ships, rather than discovering it weeks later in a Search Console report.
3. Prefer rendering JSON-LD server-side or at build time over injecting it with client-side JS
Structured data present directly in the initial HTML response removes the timing dependency entirely — there's no race between a client-side script running and a crawler capturing the page. Where client-side injection is unavoidable, use the URL Inspection tool's "View Crawled Page" / rendered HTML view in Search Console to directly confirm the JSON-LD is actually present in what Google captured, rather than assuming it based on what's visible in a regular browser.
4. Check the specific schema type's required and recommended properties against Google's rich-result documentation
A block that parses cleanly still needs to satisfy the particular requirements of whichever rich result it's targeting — verify against Google's own structured data documentation for that content type specifically (not just the broader schema.org spec), since Google's eligibility requirements for a given rich result are often narrower than what schema.org itself considers valid.
Why This Works
Each fix targets a distinct point where JSON-LD can silently fail to register: build-time validation and Google's own testing tools catch the all-or-nothing parsing failure that a single syntax slip causes; server-side rendering removes the timing gap that makes client-injected structured data invisible to a crawl even though it's genuinely present in the browser; and checking against the specific rich-result requirements catches the case where the JSON is syntactically fine but incomplete for what it's actually trying to earn. None of these fixes are cosmetic — each one closes a real gap between "the markup exists" and "Google can actually read and use it."
Conclusion
Structured data that's visibly in the page source but produces zero results in Search Console is almost never a ranking or prioritization issue — it means the JSON-LD is failing to parse, arriving too late for the crawl, or missing a field the specific rich result actually requires. Validate every deployed page directly with Google's Rich Results Test, lint JSON-LD at build time so a syntax error can't silently ship, prefer server-side rendering for structured data over client-side injection, and confirm required properties against Google's documentation for that exact schema type.
