Fetch is not parse: why broken schema still returns a clean crawl
Sources: Google Search Central; Gary Illyes.
The short version
- Google Search Central said its JSON-LD extraction now applies a single pass of HTML unescaping, so double-escaped entities are no longer unrolled and values that depended on that forgiveness now reach the indexer carrying literal entity text.
- Gary Illyes said Google's crawlers do not parse JSON at all: they download files, and a separate system such as the Search indexer does the reading.
- A parser tightening to spec produces no crawl error and no warning, so the only signal a site owner ever receives is the eventual absence of a rich result.
- Both statements were made on social platforms instead of in documentation, and neither carries an effective date, so every claim here dates to the post and not to the product.
Google changed how it reads JSON-LD, and the change announces itself to nobody. Google Search Central said on LinkedIn that its extraction now applies a single pass of HTML unescaping instead of two, so double-escaped entities no longer get unrolled.2 Four days later Gary Illyes explained, without meaning to, why you will never catch it: Google’s crawlers do not parse JSON at all.3 They download files, and a different system does the reading. Between those two statements sits a gap where your structured data can carry the wrong values while every signal you can see reports success.
Google’s crawlers download files. A separate system parses them, and only the download reports back to you.
What did Google change about JSON-LD parsing?
Google’s JSON-LD extraction now unescapes HTML once instead of twice. Search Central put it this way: “To bring our parser up to JSON and other standards, we changed our JSON-LD extraction and are now only applying a single pass of HTML unescaping.”2 Double-escaped entities will no longer be unrolled, and sites should move to standard JSON escapes or Unicode hexadecimal escapes.2
Gary Illyes pointed developers to RFC 8259, the technical specification that defines the JSON format, as the authority on proper escaping.5 Search Engine Roundtable reported both statements together on August 21.1 Underneath the standards language is an ordinary templating bug. A template renders a product name containing an ampersand, HTML-encodes it on the way out, then serializes the already-encoded string into a JSON-LD block. What lands on the page is the encoding of an encoding:
What you meant: Ben & Jerry's
What the page holds: Ben & Jerry's
Two unescape passes turned that back into an ampersand and nobody noticed the defect. One pass leaves & sitting in the value, and the string that reaches the indexer is wrong. Google is enforcing a specification the markup never met, which is a fairer description than saying Google broke anything.
The announcement was a LinkedIn post,2 not documentation, and it carries no date. Its past tense means the change was already live when Search Engine Roundtable reported it on August 21, 2026.1 When it started is unknown, and anyone telling you which morning your schema broke is guessing.
Why does a parser tightening produce no error?
Nothing in a site owner’s toolkit watches for a parser tightening like this one, and the reason is worth being precise about. A single unescape pass usually does not break JSON syntax at all. Leaving & inside a string is perfectly legal JSON, so the block still parses and the object is still valid.
What changes is the value the indexer ends up holding. Your product is now named “Ben & Jerry’s” and every check you own reports success.
Where the field is typed, the same defect surfaces as a validation failure instead of a wrong string. A price that arrives as 19.99 is not a number, so Google rejects the offer while the page it came from stays healthy by every measure you can query. Same cause, different symptom, and neither one raises an exception anywhere you are looking.
The absence of a signal is the whole problem. Rich results stop appearing, and they stop gradually, on Google’s own recrawl and reprocess schedule rather than on the day of your deploy. Schema-backed AI citations thin out over weeks. By the time anyone connects the drop to a cause, the deploy that introduced it is months of commits back.
Compare that to a defect with a channel. A broken canonical throws a Search Console warning, a 500 shows up in Crawl Stats, and a robots.txt mistake surfaces in the tester. Each has somewhere to report. This one reports nowhere, which is why it can run for a quarter before anybody looks.
Do Google’s crawlers parse the files they download?
By Illyes’ own account, Google’s crawlers never parse the files they download. He stated it directly on Bluesky on August 25, 2026: “Google’s crawlers don’t parse JSON, they just download things. Parsing anything is done by, for example, indexing in case of Search.”3 One system collects the file and a second system decides what it means.
It works much like a mail carrier and the person who opens the envelope, since delivery and reading are separate acts by separate parties. The analogy breaks on who reports back, because a carrier at least tells you the letter arrived at the right house, and here the delivery confirmation is the only message you ever get.
That statement reorganizes how the previous section should be read. The crawler and the parser are separate systems with separate jobs, and only the crawler produces the telemetry a site owner can see. Crawl Stats reports what the crawler did, which is fetch a file. Whether the file made sense is decided later, elsewhere, by a system that reports to Google and not to you.
Defining the pattern, the fetch-parse gap is the interval between a successful download and a successful read, during which every available signal says the pipeline is healthy. It is not specific to JSON-LD. Any format Google fetches and then hands to a second system for interpretation inherits the same blind spot, and the site owner’s view stops at the handoff.
What does that mean for a Merchant Center feed?
Asked whether Merchant Center follows the same fetch-then-parse split as Search, Illyes answered: “we generally use shared infrastructure so we don’t have to reinvent the wheel all the time. I’m very certain MC uses the same parser, but I never worked with that team.”4
Read that quote precisely, because its two halves do different work. A Google engineer saying his employer shares parsing infrastructure is worth something. The same engineer saying he never worked with the team that owns the system he is describing is a limit on how far the claim travels. Suspected, not documented, and the article’s advice should not rest on it alone.
The useful part rests on the general statement instead, which is confirmed. If crawlers download and separate systems parse, then a feed file fetched successfully has cleared exactly one bar. Whether the field values inside it were read correctly is a different question answered by a different system, and the fetch log cannot speak to it. Anyone debugging a Merchant Center error against crawl logs is reading the wrong instrument, and that holds whether or not Merchant Center shares Search’s specific parser.
How do you check whether your own markup broke?
Start with the raw response, since that’s where the HTML-unescaping defect lives. Fetch a product page with curl or any client that does not execute JavaScript, and search the JSON-LD block for a doubled ampersand entity or a numeric entity pattern. A template that HTML-encodes a value before serializing it into JSON is the exact case this change breaks.
The fastest tell is finding & inside a JSON string value where a plain character belongs.
Then run the affected page through the Rich Results Test. Markup that validated in July carries no guarantee for August, and the test is the only tool that reports on the parse rather than on the fetch.
Two places to look first. Product names and titles are where ampersands and special characters cluster, and they’re also the fields most often assembled by string interpolation instead of by a serializer. Anything a merchandiser types into a CMS field is the second, because free-text input is where the encoding path gets least attention.
The durable fix is upstream of the markup. Build the JSON-LD object in code and let a real serializer emit it. A serializer is code whose only job is turning data into the text format a machine reads, so escaping happens once, in one place, by a function that knows the rules. Hand-assembled JSON strings inside an HTML template will keep reproducing this defect no matter how many times the entities get cleaned up.
Does this confirm the crawler split?
Illyes’ Bluesky statement confirms the crawler split from a second and independent direction. This site argued in Google’s crawler split that the Shopping crawler behaves as an HTML-only reader for structured data, and flagged that the conclusion rested on a Google engineer’s spoken remarks at Search Central Live Zurich plus the Merchant Center documentation, without a published specification behind it.
Illyes’ statement is a second and independent data point for the same split, arriving eight months later through a different channel and generalized past structured data to JSON as a whole. Two Google engineers, two venues, one architecture: fetching and interpreting are separate stages, and the separation is a design choice about throughput rather than an implementation detail.
One caution about how much weight that carries. Both statements are still spoken and social, and neither is documentation anyone can diff against a previous version. The behavior is now well attested. The architecture remains described rather than published, and a reader deciding how much to build on it should price that in.
What survives all the hedging is small and practical. A green crawl is not a green parse, and no tool you have will tell you the difference.
Terms defined here
- The fetch-parse gap. The interval between a crawler successfully downloading a file and a separate system successfully reading it, during which every signal available to the site owner reports success.
Sources
- Search Engine Roundtable: JSON-LD Extraction For Googlebot Now Does One Pass Of HTML Unescaping
- Google Search Central (LinkedIn): the JSON-LD extraction change
- Gary Illyes (Bluesky): Google's crawlers don't parse JSON, they just download things
- Gary Illyes (Bluesky): follow-up on Merchant Center's parser
- Gary Illyes (LinkedIn): JSON escaping is defined in RFC 8259 section 7
Recent developments
Related reading
This piece elsewhere