TL;DR
- Google said on LinkedIn that it changed its JSON-LD extraction and now applies only a single pass of HTML unescaping, so double-escaped entities are no longer unrolled.
- Search Engine Roundtable reported the change on 21 August 2026, sourced to Google's LinkedIn post; Gary Illyes of Google pointed site owners to RFC 8259, section 7 for proper JSON escaping.
- Google asked site owners to update code to standard JSON escapes or Unicode hexadecimal escapes; single-escaped entities still resolve because one pass is still applied.
- Google gave no enforcement date, no grace period, no estimate of affected sites and no indication that Search Console will notify anyone whose structured data breaks.
- Rich result eligibility can lapse without an error reaching the site owner, which is why checking the raw page source now beats waiting for a report.
Googlebot now applies exactly one pass of HTML unescaping when it pulls JSON-LD out of a page, and structured data that relies on a second pass will stop resolving. Google announced the change in a post on LinkedIn, writing: "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." Search Engine Roundtable reported the change on 21 August 2026, sourced to that LinkedIn post, and its write-up is at Search Engine Roundtable. The practical consequence is that markup which was previously repaired by Google's parser is now taken literally, and the failure is quiet.
Google set out the consequence in the same post: "Practically speaking, this means that double-escaped entities (like & or ✔) will no longer be unrolled. If you're using JSON-LD for structured data, be sure to update your code to standard JSON escapes or Unicode hexadecimal escapes (like \u0026)." Gary Illyes of Google added a pointer to the specification: "If you're wondering what *proper* escaping is in JSON, I have good news for you! It's very, very well defined in RFC 8259, specifically section 7."
What Googlebot reads, and why the escaping matters at all
Google uses the script element with the type application/ld+json to read entity detail from a page, including product prices, review stars, recipe ingredients and FAQs, and turns that detail into rich results. The block is a JSON document sitting inside an HTML document, which is where the two layers of escaping come from. The extractor has to decide how to treat the text between the opening and closing script tags before it can hand anything to a JSON parser.
Under the old behaviour, that text went through more than one round of HTML unescaping, so a value that had been escaped twice was unwound back to the character the author meant. Under the new behaviour, one round is applied and the result is passed on as-is. Everything that survives exactly one round keeps working. Everything that needed two rounds now arrives at the parser carrying entity text as literal characters.
Where double-escaped output comes from
This is a technical explanation rather than something Google spelled out, and it is the part worth checking in your own stack. Double escaping is almost never written by hand. It is produced by a template layer.
The usual sequence runs like this. A value, say a product name containing an ampersand, is serialised into JSON correctly. The JSON string is then handed to a template that writes it into the page. That template applies HTML escaping to everything it outputs, because that is what an auto-escaping template engine is built to do, and it does not know that this particular block is a JSON payload rather than page text. The ampersand becomes an HTML entity. If the value had already been HTML-escaped once before serialisation, which happens when content is stored escaped in a database or passed through a sanitiser, the escaping is applied to the escaped form and the entity itself gets escaped a second time.
Worth knowing, because it explains why this was always fragile: the content of an HTML script element is raw text. An HTML parser does not decode character references inside it. To a browser, an HTML entity written inside a JSON-LD block is simply that run of literal characters and nothing more. Google applying even one pass of HTML unescaping is more forgiving than a strict reading of the markup would be. The change narrows the leniency rather than removing it.
What RFC 8259 section 7 actually specifies
Illyes pointed at the specification rather than at a Google document, so it is worth stating what section 7 of RFC 8259 covers. This is standards material, not a Google rule.
Section 7 defines JSON strings. A string is a sequence of Unicode code points wrapped in quotation marks. Any code point may appear literally inside those quotation marks except three groups: the quotation mark itself, the reverse solidus, and the control characters from U+0000 to U+001F. Those must be escaped.
The escaping mechanism has two forms. The first is a set of two-character sequences beginning with a reverse solidus, covering the quotation mark, the reverse solidus, the solidus, backspace, form feed, line feed, carriage return and tab. The second is the six-character form: a reverse solidus, the letter u, and four hexadecimal digits naming a code point, which is what Google means by Unicode hexadecimal escapes. Code points above the Basic Multilingual Plane are written as a pair of these six-character escapes forming a UTF-16 surrogate pair.
Notice what is not on that list. An ampersand does not need escaping in JSON. Neither does an accented letter, a Thai character or a currency symbol. The reason so much JSON-LD in the wild is full of HTML entities is not that JSON required them. It is that an HTML layer put them there.
The same string, before and after the change
The table below works through the single-pass rule against the two examples Google gave, plus the form Google recommends. It is the implication of Google's statement rather than a table Google published, so treat the mechanism as the point rather than the exact glyphs.
| What sits in the raw page source | Value extracted before the change | Value extracted now |
|---|---|---|
| A single HTML entity, such as & | & | & |
| An entity that has itself been escaped again, such as & | & | & |
| A double-escaped numeric reference, such as ✔ | The check mark character | ✔ |
| A JSON Unicode hexadecimal escape, \u0026 | & | & |
| A raw ampersand character with no escaping | & | & |
How this breaks, and why nobody gets told
There are two failure shapes and they are not equally visible. In the milder one, the JSON still parses and the value is simply wrong: a product name renders with entity text sitting inside it, a price string carries characters that are not digits, an FAQ answer reads with markup residue in the middle of a sentence. The markup is valid, the data is wrong, and the page keeps its structured data while losing the accuracy that made it eligible for a rich result.
In the harsher one, the JSON does not parse at all, and every entity described in that block disappears from Google's view of the page at once. A single template that writes escaped output into every product page can take an entire catalogue's structured data with it.
The reason to check rather than wait is that neither shape announces itself. Rich result eligibility can lapse without an error reaching the site owner. Nothing in Google's post said a notification would be sent, and losing eligibility is not the same as receiving a penalty or a warning. The visible symptom, if there is one, arrives later as review stars or price detail quietly missing from search listings, which is the kind of change that gets noticed in a monthly report rather than on the day it happens. Anyone running SEO in Thailand for a catalogue site has a reason to look this week rather than next quarter.
How to check your own site
The workflow below is a description of the checking process rather than a Google instruction, and it is deliberately manual at the first step.
Start with the raw response the crawler receives. Fetch the page source directly rather than reading a rendered inspector view, because any tool that decodes entities in order to display them will hide the exact characters you are trying to see. Find the JSON-LD block in that raw text and read the string values as bytes rather than as they render.
Then search the raw source for the patterns that indicate a second escaping layer: a run beginning with an ampersand entity followed immediately by more entity text, and any numeric character reference whose leading ampersand is itself an entity. A grep across a saved copy of the page is enough. If either pattern appears inside a JSON-LD block, that page is affected.
Test one affected page in Google's Rich Results Test and in the Schema Markup Validator, then fix and retest. Both tools read the markup rather than the index, so they will show whether the corrected block parses. Google's post did not describe what either tool reports for this specific problem, so run the before-and-after rather than looking for a particular message.
Finally, treat this as a template problem rather than a page problem. Structured data on most sites is generated by one code path, so one page carrying double-escaped output usually means every page from that template carries it. Fix the serialisation once, at the point where the JSON string is written into the page, and verify a sample across each template type. A scheduled SEO audit that already crawls the site can add the same pattern check across every URL rather than a handful.
What Google did not say
The post was short and several obvious questions went unanswered. Listing them is more useful than guessing at them.
- No enforcement date or grace period was given. Google described the change in the past tense, as something already applied, and did not offer a window for fixing markup before it takes effect.
- No estimate of how many sites are affected was published, and no share of pages or markup types was quantified.
- No list of affected rich result types was given beyond the general warning. Google named product prices, review stars, recipe ingredients and FAQs as the kinds of detail JSON-LD carries, but did not say which of those have stopped resolving on which sites.
- No indication was given that Search Console will notify anyone whose structured data has broken, and nothing in the post described a report or an alert.
- Nothing was said about when previously-extracted markup gets re-evaluated, so how quickly a fix is reflected is not established by the source.
Search Engine Roundtable's report is sourced to the LinkedIn post and points readers to the discussion there. There is no separate Google Search Central documentation update described in the report.
What this means for Thai marketers
This section is analysis rather than something the source stated. Thai-language sites have a sharper version of this problem than English-language ones, and it comes down to how Thai text tends to travel through a publishing stack.
Thai characters need no escaping in JSON. They sit in the Basic Multilingual Plane, in the block from U+0E00 to U+0E7F, so they are valid as raw UTF-8 inside a JSON string and, where escapes are wanted, a single six-character Unicode hexadecimal escape covers each one with no surrogate pair required. Either form is standards-compliant and both survive the change untouched.
What does not survive is Thai text pushed through an HTML-entity escaping layer. Some content pipelines convert non-ASCII characters into numeric character references on output, which turns a Thai product name into a long run of numeric entities. Under the previous behaviour that could still be unwound. Under single-pass extraction, a numeric reference whose own ampersand has been escaped stays literal, and a Thai product title in structured data becomes a string of digits and semicolons. This is the pattern the change punishes, and it is more common in stacks that were built to be safe with Thai text than in stacks that simply emit UTF-8.
The check is the same one described above, run against a Thai URL rather than an English one, and it is worth running on both language versions of a bilingual site because the two often pass through different template paths. For teams working on how AI answer surfaces read a site, the same block is doing double duty, since clean, parseable entity data is the machine-readable layer that generative engine optimisation depends on. Structured data that fails to parse is invisible to anything reading it, not only to Google Search.
Frequently asked questions
Do I have to do anything if my structured data already works?
Only if your markup contains double-escaped entities, which is something you have to look at the raw source to know. Markup that uses raw characters, standard JSON escapes or Unicode hexadecimal escapes is unaffected, and Google's post described the change as bringing its parser up to the JSON standard rather than adding a new requirement. Single-escaped entities still resolve, because one pass is still applied.
Is this live in Thailand?
The source did not say. Google described a change to how Googlebot extracts JSON-LD and made no mention of regional rollout, market-by-market timing or language-specific behaviour. Extraction changes of this kind are normally properties of the crawler rather than of a locale, but nothing in the post confirms that, so treat it as unstated.
How do I tell whether my pages are affected?
Read the raw page source rather than a rendered inspector, find the JSON-LD block, and look for an ampersand entity immediately followed by more entity text. Then run one affected URL through Google's Rich Results Test and the Schema Markup Validator before and after a fix. Google did not say what those tools report for this specific case, so compare the two runs rather than searching for a named error.
Will Google tell me if my rich results stop working?
The source did not say, and nothing in Google's post mentioned a Search Console notification. Losing rich result eligibility is not a manual action and does not generate a warning of its own, which is the reason an active check is worth more here than waiting for a report.
What counts as proper escaping in JSON?
Gary Illyes pointed at RFC 8259, section 7, which defines JSON strings. It requires escaping only for the quotation mark, the reverse solidus and control characters from U+0000 to U+001F, using either the two-character reverse solidus sequences or the six-character form with four hexadecimal digits. HTML entities are not part of that specification, which is why Google asked for standard JSON escapes or Unicode hexadecimal escapes instead.
If your product, review or FAQ markup is generated by a template you have not inspected since it was built, this is a cheap thing to verify and an expensive thing to discover late. A single look at the raw source of one product page will tell you whether the rest of the catalogue needs attention.







