Server-side rendering sends a fully-formed HTML page to the browser, and client-side JavaScript then “hydrates” that HTML, attaching interactivity and, in many frameworks, updating or supplementing content after the initial render. When hydration fails partway through during Googlebot’s render pass, due to a JavaScript error, a timeout, or a mismatch between what the server rendered and what the client expects, Google can end up indexing the pre-hydration HTML while actual users, whose browsers usually complete hydration successfully, see the fully hydrated, updated version. Unlike a pure client-side-rendering failure, where nothing meaningful renders at all, a failed hydration still produces something that looks like a complete page, it’s just the wrong or stale version, which makes this failure mode harder to notice than an outright blank-page failure.
The mechanism: hydration as a second step that can partially fail
In the SSR-plus-hydration model common to frameworks like React, Vue, Next.js, and Nuxt, the server generates and sends complete HTML for the initial request, solving the problem of a crawler or slow connection seeing a blank page (the classic pure-client-side-rendering issue). Client-side JavaScript then takes over, attaching event listeners, and in many implementations also reconciling or replacing parts of that server-rendered content with client-side state, fetching updated data, applying user-specific logic, or otherwise finishing what the server-rendered version only approximated.
Google’s rendering pipeline for JavaScript-heavy pages runs on an evergreen, up-to-date Chromium engine, executing JavaScript much as a real browser would, which in principle should complete hydration the same way a user’s browser does. But hydration failure modes exist independent of which engine is running the JavaScript: a script error partway through the hydration process, a timeout under Google’s rendering resource constraints, a mismatch between the exact markup the server produced and what the client-side code expects to find (a common category of bug in these frameworks generally, not unique to bots), or a dependency or API call the hydration process depends on failing or being blocked. When any of these occur during Google’s render pass specifically, and don’t occur (or occur less often) during a typical real user’s session, the result is that Google’s indexed version reflects the pre-hydration state while real users predominantly see the post-hydration state.
Why this is distinct from the standard two-wave delay
It’s worth distinguishing this from the more commonly discussed two-wave indexing delay, where Google simply hasn’t gotten around to rendering a page yet and is working from raw HTML in the meantime. That’s a timing/queueing issue, eventually resolved once the render happens. A hydration failure is a different category: the page was rendered, JavaScript did execute, but it broke partway through rather than completing successfully, so Google isn’t merely behind, it’s stuck with an incorrect version even after rendering supposedly happened. This means simply waiting longer, which resolves a queueing delay, doesn’t resolve a hydration failure, since the failure recurs on every render attempt until the underlying bug or resource issue causing it is fixed.
This distinction matters for troubleshooting: if a diagnostic check shows Google’s rendered output is stale or missing content that a real user reliably sees, the fix path depends on which of the two situations is actually occurring, whether the page simply hasn’t been re-rendered recently (a queueing/priority issue) or whether the render is happening but consistently failing to hydrate correctly (a code-level bug that needs fixing regardless of render timing).
Common underlying causes worth checking
Hydration mismatches often stem from differences between what the server actually rendered and what the client-side code expects when it starts reconciling, timestamps or randomized values that differ between server and client render passes, conditional rendering based on browser-only APIs unavailable during Google’s render environment, or state that depends on a fetch call that resolves differently (or fails, or times out) under Google’s rendering conditions than it typically does for a real user’s connection and browser. Resource-loading issues, blocked scripts via robots.txt, slow-loading dependencies that exceed rendering time budgets, can also interrupt hydration specifically for the crawler’s render pass without necessarily affecting most real users in the same way.
Practical implication
Use the URL Inspection tool’s rendered HTML/screenshot view in Search Console to see what Google’s render pass actually produced for a given URL, and compare it directly against what a real browser shows after full hydration completes, checking specifically for content, interactive elements, or data that’s present in the live user experience but missing or stale in Google’s rendered version. If a discrepancy shows up consistently across repeated inspections rather than resolving after a wait, that points to a hydration failure rather than a simple rendering-queue delay, and the fix needs to happen at the code level, resolving the specific JavaScript error, timeout, or server/client mismatch causing hydration to break, rather than assuming more time will resolve it. Testing in an environment that mirrors Google’s rendering conditions as closely as practical (checking for console errors during a fresh, unauthenticated load without cached state) helps surface the same hydration failures Google’s crawler would encounter, since local development testing with a warm cache and existing session state often doesn’t reproduce the exact conditions under which hydration mismatches actually occur.