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

  1. 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.
  2. Ensure server and client receive identical initial data for the hydrating component.
  3. Temporarily set recover: true (default) to see the recovered DOM and isolate which node mismatches, then fix the root cause.
  4. 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

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


AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12). Data as JSON: /api/errors/3f644a53a95f669e. Report an issue: GitHub.