Hydration Proof

Search documentation

Find a page or section

React hydration error messages

The exact strings React prints, by version, with a page for each.

React hydration error messages mean React could not reuse the HTML the server sent: the first render in the browser produced different markup, or something failed while React attached to the page. The wording depends on your React version and on whether the build is minified. Find the text you see below and open its page for the fix.

Every message, by React version

React 19 merged most of the React 18 messages into one error with a diff, and production builds replace every message with a numbered code.

PageReact 18 wordingReact 19 wordingCode
Server rendered HTML didn't matchNot in React 18Hydration failed because the server rendered HTML didn't match the client.#418
Initial UI does not matchHydration failed because the initial UI does not match what was rendered on the server.Replaced by the row above#418
Text content does not matchText content does not match server-rendered HTML. and the warning Text content did not match. Server: … Client: …Hydration failed because the server rendered text didn't match the client.#425 in 18, #418 in 19
Attributes didn't matchOne warning per attribute (the next two rows)A tree hydrated but some attributes of the server rendered HTML didn't match the client properties.None: development only
Prop className did not matchWarning: Prop `className` did not match. Server: … Client: …A line in the attribute diffNone
Expected server HTML to containWarning: Expected server HTML to contain a matching <div> in <div>.A + or - element in the diff#418 follows it
Extra attributes from the serverWarning: Extra attributes from the server: class,styleA - line in the attribute diffNone
Error while hydratingThere was an error while hydrating. (root) or …this Suspense boundary.There was an error while hydrating but React was able to recover…#423, #422
div cannot be a descendant of pvalidateDOMNesting(...): <div> cannot appear as a descendant of <p>.In HTML, <div> cannot be a descendant of <p>.None: development only
validateDOMNestingvalidateDOMNesting(...): <tr> cannot appear as a child of <table>.In HTML, <tr> cannot be a child of <table>.None: development only
Update before hydratingThis Suspense boundary received an update before it finished hydrating.No longer reported#421
Missing getServerSnapshotMissing getServerSnapshot, which is required for server-rendered content.Same#407
window is not definedReferenceError: window is not definedSame: a server crash, not a React errorNone

The production codes have their own pages: minified React error #418, #423, #425, and every hydration code in one table.

Which one am I seeing?

Look at how the message starts:

It starts withWhat happenedGo to
Minified React error #A production build. The text is replaced by a codeMinified React error codes
Hydration failed becauseReact threw the server HTML away and rendered it again in the browserReact 19 or React 18
Warning:A React 18 development warning that names the element and both valuesThe matching row in the table above
A tree hydrated butReact 19 kept the page, but an attribute differs and stays wrongAttributes didn't match
In HTML, or validateDOMNestingInvalid tag nesting that the browser rewrites before React runsvalidateDOMNesting
There was an error while hydratingThe follow-up to an earlier error. Scroll up to the first oneError while hydrating
ReferenceErrorThe server crashed before any hydration happenedwindow is not defined

React prints several of these for one bug. In React 18 a single mismatch often logs a warning, then Hydration failed… or Text content does not match…, then There was an error while hydrating…. The first message is the one that names the element. Fix that one first.

To see which wording you get, check the React version your app uses:

npm ls react react-dom   # pnpm why react · yarn why react · bun pm ls

Next.js 15 and later run the App Router on React 19. Next.js 13 and 14 print the React 18 wording.

Find the cause, whatever the message

Each message is a symptom. The same few causes produce all of them: the clock, the user's locale or timezone, window and localStorage read during render, invalid HTML, CSS-in-JS class names, browser extensions and scripts that edit the page first. Common causes of hydration errors has a fix guide for each, and the React hydration error guide explains the mechanism behind all of them.

To find every mismatch in an app at once, instead of one console message at a time, load every route with hydration-proof:

npx hydration-proof test --mode both

It reports each difference with a stable issue code, the element, the server and client values, the source line and the likely cause.