# HP2003: A Suspense boundary switched to client rendering

> HP2003 (boundary client rendered): React could not hydrate a Suspense boundary and rendered it on the client instead (React error #422). What to check first.

Source: https://hydration.jscrate.dev/docs/issues/hp2003
Last updated: 2026-09-18

HP2003 (`boundary-client-rendered`) means React could not hydrate a Suspense
boundary and rendered its content on the client instead, throwing the server
HTML inside it away. The rest of the page hydrated normally. Check the error
React reported for the boundary: until it is fixed, the boundary is rendered on
the client on every load.

| | |
| --- | --- |
| Code | `HP2003` |
| Name | `boundary-client-rendered` |
| Default severity | Error |
| Group | Problems React reported |
| What it means | React could not hydrate a Suspense boundary and rendered it on the client instead. |

## What HP2003 (`boundary-client-rendered`) means

When hydration fails inside a Suspense boundary, React recovers there: it
discards the boundary's server HTML and renders it from scratch, and logs why.
hydration-proof compares each boundary's hydration commit on its own, so it
usually also sees the difference React hit and reports that (a DOM code such
as [HP1001](https://hydration.jscrate.dev/docs/issues/hp1001), or [HP1010](https://hydration.jscrate.dev/docs/issues/hp1010) for the
replaced branch), with React's message as evidence.

HP2003 stands alone when React reported the switch and no DOM finding from that
commit explains it, for example because the difference is inside a subtree
excluded with `ignore.selectors`. When React attaches the original error, the
finding shows it after "Caused by:".

## The React error it matches

```text
There was an error while hydrating this Suspense boundary. Switched to client rendering.
```

This is React 18's message; production builds show
[minified error #422](https://hydration.jscrate.dev/docs/errors/minified-react-error-codes). See
[there was an error while hydrating](https://hydration.jscrate.dev/docs/errors/there-was-an-error-while-hydrating).
If the failure is outside every boundary, the whole root switches instead:
[HP2004](https://hydration.jscrate.dev/docs/issues/hp2004).

## Likely causes

- A mismatch inside the boundary: a [time](https://hydration.jscrate.dev/docs/causes/time) value,
  [browser storage](https://hydration.jscrate.dev/docs/causes/storage) or a
  [browser-only API](https://hydration.jscrate.dev/docs/causes/browser-api) branch.
- Data the client fetched again and got a different answer:
  [different data](https://hydration.jscrate.dev/docs/causes/data).
- [Invalid HTML](https://hydration.jscrate.dev/docs/causes/invalid-html) the browser repaired inside the
  boundary.

## How to fix it

- Check the error React reported for this boundary; the boundary is rendered on
  the client until it is fixed.

1. Open the finding in the HTML report. Its evidence has React's message, the
   underlying error when there is one, and the component stack.
2. Run `npx hydration-proof test --mode dev` for readable component names and
   source lines.
3. Fix the difference React found, using the page of the matching DOM code
   or cause, and run the test again.

## Example

```text
  ✖ /dashboard 1.5s  1 error
    HP2003 A Suspense boundary switched to client rendering
      in UsageChart
      There was an error while hydrating this Suspense boundary. Switched to client rendering.
      → Check the error React reported for this boundary; the boundary is rendered on the client until it is fixed.
```

## Related

- [HP1010: React re-rendered a branch](https://hydration.jscrate.dev/docs/issues/hp1010)
- [HP2004: the whole root switched](https://hydration.jscrate.dev/docs/issues/hp2004)
- [HP2006: the server could not finish a boundary](https://hydration.jscrate.dev/docs/issues/hp2006)
- [There was an error while hydrating](https://hydration.jscrate.dev/docs/errors/there-was-an-error-while-hydrating)
