sveltejs/svelte · error · Error
hydration_failed
hydration_failed
Error message
hydration_failed Failed to hydrate the application https://svelte.dev/e/hydration_failed
What it means
Thrown at internal/client/render.js:138 when hydration encounters a mismatch and options.recover is false. By default Svelte recovers from hydration mismatches by re-rendering from scratch; with recover:false any mismatch is fatal, surfacing as this error so you are forced to fix the server/client divergence.
Source
Thrown at packages/svelte/src/internal/client/errors.js:344
throw error;
} else {
throw new Error(`https://svelte.dev/e/hydratable_missing_but_required`);
}
}
/**
* Failed to hydrate the application
* @returns {never}
*/
export function hydration_failed() {
if (DEV) {
const error = new Error(`hydration_failed\nFailed to hydrate the application\nhttps://svelte.dev/e/hydration_failed`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/hydration_failed`);
}
}
/**
* Could not `{@render}` snippet due to the expression being `null` or `undefined`. Consider using optional chaining `{@render snippet?.()}`
* @returns {never}
*/
export function invalid_snippet() {
if (DEV) {
const error = new Error(`invalid_snippet\nCould not \`{@render}\` snippet due to the expression being \`null\` or \`undefined\`. Consider using optional chaining \`{@render snippet?.()}\`\nhttps://svelte.dev/e/invalid_snippet`);
error.name = 'Svelte error';
throw error;
} else {
throw new Error(`https://svelte.dev/e/invalid_snippet`);
}
}View on GitHub (pinned to 20b341f100)
Solutions
- Make the offending render output deterministic — move non-deterministic work (dates, randomness, browser APIs) into onMount or an effect so SSR and initial client render agree.
- Ensure server and client receive identical initial data for the hydrating component.
- Temporarily set recover: true (default) to see the recovered DOM and isolate which node mismatches, then fix the root cause.
- Use DEV mode hydration warnings to locate the exact mismatch node.
Example fix
// before — non-deterministic output
<h1>{new Date().toLocaleTimeString()}</h1>
// SSR time != client hydration time -> mismatch
// after
<script>
let time = $state('');
onMount(() => { time = new Date().toLocaleTimeString(); });
</script>
<h1>{time}</h1> Defensive patterns
Strategy: try-catch
Validate before calling
// Before enabling recover:false, ensure deterministic render output. // Audit templates for: Date.now(), Math.random(), window/document access, time-based formatting. // Move non-deterministic work into onMount/$effect so SSR and first client render match.
Try / catch
// Hydration errors can be caught at the mount call site:
try {
mount(App, { target, hydrate: true, recover: false });
} catch (e) {
// fall back to non-hydrating mount
target.innerHTML = '';
mount(App, { target });
} Prevention
- Avoid non-deterministic values (dates, randomness) in component render bodies.
- Keep SSR and client initial data identical.
- Run the app in DEV mode to see hydration mismatch warnings before enabling recover:false.
- Consider recover:true (default) for production resilience once SSR correctness is verified.
When it happens
Trigger: Mounting with hydrate: true and recover: false when the server-rendered HTML does not match what the client would produce — different data, time-based output, random values, browser-only APIs called during render, or template differences between server and client builds.
Common situations: Date/Math.random output in templates; using window/document during render; cached vs fresh SSR data; mismatched component versions; CSS-only or feature-flag differences; enabling recover:false in tests to catch SSR bugs.
Related errors
- hydratable_missing_but_required
- invalid_snippet
- svelte_boundary_reset_onerror
- each_key_duplicate
- each_key_volatile
AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12).
Data as JSON: /api/errors/3f644a53a95f669e.
Report an issue: GitHub.