Skip to content
← Tilbage til Learn
Structured Data Advarsel

Invalid structured data

Invalid JSON-LD costs rich-result eligibility and can quietly trip quality signals. Read the validator, fix required properties, re-test.

Invalid Schema.org markup is worse than missing markup. Missing markup leaves you with no rich result. Invalid markup convinces Google’s parser to discard the block entirely — and a pattern of invalid structured data can quietly trip a quality flag.

Most invalid schema is fixable in under a minute once you read the validator output. Most of it comes from one of three causes: a missing required property, a wrong type, or invalid nesting.

How to detect it

Three validators worth knowing:

  1. Google Rich Results Testsearch.google.com/test/rich-results. Tells you which rich-result types the page is eligible for and what’s missing.
  2. Schema.org Validatorvalidator.schema.org. Validates raw schema.org correctness without Google’s rich-result filter.
  3. Google Search Console → Enhancements — production signal. Shows real errors and warnings Google’s parser hit during crawl, broken down by URL and by error type.

Use Rich Results Test for debugging. Use Search Console for monitoring at scale.

The four most common errors

1. Missing required property

Most Schema.org types have required properties for rich-result eligibility. Missing one disqualifies the entire block.

Common examples:

  • Article without headline or image
  • Product without name or offers
  • Recipe without recipeIngredient
  • Event without startDate

Fix: read the Rich Results Test output. It tells you which property is missing.

2. Wrong type for a property

Common examples:

  • Date as a string ("May 1, 2026") instead of ISO 8601 ("2026-05-01").
  • Price as a number (99.00) — valid here — vs. price as a string ("99.00") — also valid; mixing both across pages confuses your downstream.
  • A single value where the schema expects an array ("image": "url" is allowed; "image": ["url1", "url2"] is also allowed, just be consistent).
  • A free-text string where Schema.org wants a controlled enum (availability: "In Stock" vs. availability: "https://schema.org/InStock").

3. Invalid nesting

Article requires a Publisher of type Organization, which requires a logo of type ImageObject. Forgetting any level of @type breaks the chain:

// invalid — Publisher is missing @type
"publisher": { "name": "Acme", "logo": { "url": "..." } }

// invalid — logo is a bare string when ImageObject is required
"publisher": { "@type": "Organization", "name": "Acme", "logo": "..." }

// valid
"publisher": {
  "@type": "Organization",
  "name": "Acme",
  "logo": { "@type": "ImageObject", "url": "https://example.com/logo.png" }
}

4. Malformed JSON

A trailing comma, a stray HTML entity inside the script (&quot; instead of "), an unescaped </script> in a description. The whole block fails to parse.

The fix: ensure your templating engine emits valid JSON. Don’t HTML-escape the contents of a <script type="application/ld+json"> block — JSON is not HTML.

<!-- bad: template HTML-escaped the quotes -->
<script type="application/ld+json">
{&quot;@context&quot;: &quot;https://schema.org&quot;}
</script>

<!-- good -->
<script type="application/ld+json">
{"@context": "https://schema.org"}
</script>

For content that does need escaping (a description containing </script>), use Unicode escape (</script>) — not HTML escape.

The fix — per platform

WordPress

Yoast and Rank Math both emit schema. Invalid markup usually comes from:

  • A custom field someone added that conflicts with auto-output.
  • Two plugins both emitting schema (the duplicate block confuses validation).
  • A theme that emits its own JSON-LD on top of the plugin’s.

Audit by viewing source on a representative page — count the number of application/ld+json blocks. More than one of the same @type is the bug.

Shopify

Most Shopify theme schema errors come from missing offers data — a product with no price, no SKU, or availability set to a free-text string. The theme typically tries to emit Product even when the data isn’t there.

Fix in templates/product.liquid by skipping Product JSON-LD when required fields are missing:

{% if product.price and product.available != null %}
  <script type="application/ld+json">
    { "@type": "Product", "name": "{{ product.title }}", "offers": { "price": "{{ product.price | money_without_currency }}" } }
  </script>
{% endif %}

Next.js / React

The biggest source of invalid JSON-LD in JS frameworks: stringifying objects with embedded HTML or unescaped characters.

// safe — JSON.stringify handles escaping
<script
  type="application/ld+json"
  dangerouslySetInnerHTML={{ __html: JSON.stringify(ld) }}
/>

Don’t template the JSON by string concatenation; let JSON.stringify handle escaping.

Static HTML

Run a build-time validator. If your build emits JSON-LD, parse it in CI and fail the build on any invalid block.

# in CI
node -e 'const fs=require("fs"); const m=fs.readFileSync("dist/index.html","utf8").match(/<script type="application\/ld\+json">([\s\S]*?)<\/script>/g); m.forEach(b=>{ try { JSON.parse(b.replace(/<script[^>]*>|<\/script>/g,"")); } catch(e) { console.error(e); process.exit(1); }});'

Pitfalls

Don’t ignore Search Console warnings. Warnings (vs errors) don’t disqualify you from rich results today but often become errors in a future Google update. Fix them when you see them.

Don’t fake aggregateRating to fix a “missing required property.” If you don’t have reviews, drop the rich-result type entirely. Fabricated ratings are a manual-action risk.

Don’t ship JSON-LD that contradicts the visible page. Schema is meant to describe what’s there, not what you want to be ranked for.

Don’t use HTML entities (&quot;, &#34;) inside <script type="application/ld+json">. That’s HTML escaping inside a JSON context — invalid.

Fix at the edge with Serpwise

Invalid schema across a site is usually a template problem multiplied — one missing field in one template ships invalid markup on tens of thousands of URLs.

Serpwise can rewrite JSON-LD at the edge: detect the invalid block, parse it, add missing required properties from on-page signals (image from <meta property="og:image">, author from <meta name="author">, date from the rendered byline), serialize valid output, ship. The corrected schema lands on every URL in the pattern in minutes; the long-term template fix happens on its normal schedule.

See pricing or run a free AI visibility audit.

Fra diagnose til live rettelse

Find issue'et. Få rettelsen live.

Brug Learn til at forstå problemet, og kør derefter Serpwise på dit eget site for at se, hvad der kan rettes og komme live.