sveltejs/kit · error · Error

CORS error: ${acao ? 'Incorrect' : 'No'} 'Access-Control-All

Error message

CORS error: ${acao ? 'Incorrect' : 'No'} 'Access-Control-Allow-Origin' header is present on the requested resource

What it means

When a universal `fetch` inside `load` targets a different origin, SvelteKit requires the response to carry a valid `Access-Control-Allow-Origin` header (matching the requesting origin or `*`). Missing or mismatched header means the client-side fetch would be blocked by the browser, so the server-side passthrough throws early with this descriptive error.

Source

Thrown at packages/kit/src/runtime/server/page/load_data.js:304

		if (same_origin) {
			if (prerendering) {
				dependency = { response, body: null };
				prerendering.dependencies.set(url.pathname, dependency);
			}
		} else if (url.protocol === 'https:' || url.protocol === 'http:') {
			// simulate CORS errors and "no access to body in no-cors mode" server-side for consistency with client-side behaviour
			const mode = input instanceof Request ? input.mode : (init?.mode ?? 'cors');
			if (mode === 'no-cors') {
				response = new Response('', {
					status: response.status,
					statusText: response.statusText,
					headers: response.headers
				});
			} else {
				const acao = response.headers.get('access-control-allow-origin');
				if (!acao || (acao !== event.url.origin && acao !== '*')) {
					throw new Error(
						`CORS error: ${
							acao ? 'Incorrect' : 'No'
						} 'Access-Control-Allow-Origin' header is present on the requested resource`
					);
				}
			}
		}

		/** @type {ReadableStream<Uint8Array>} */
		let teed_body;

		const proxy = new Proxy(response, {
			get(response, key, receiver) {
				/**
				 * @param {string | undefined} body
				 * @param {boolean} is_b64
				 */
				async function push_fetched(body, is_b64) {

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Configure the remote API to send `Access-Control-Allow-Origin: <your origin>` or `*`
  2. Proxy the request through your own SvelteKit `+server.js` endpoint (same-origin, no CORS needed)
  3. Fetch in a server-only `+page.server.js` load, where this CORS requirement doesn't apply

Example fix

// before (universal load, direct third-party fetch)
const res = await fetch('https://api.example.com/data');
// after (proxy via local endpoint)
const res = await fetch('/api/data'); // +server.js proxies to https://api.example.com/data
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const res = await fetch('https://api.example.com/data');
  if (!res.ok) throw new Error(`API error: ${res.status}`);
  return { data: await res.json() };
} catch (e) {
  if (String(e).includes('CORS')) {
    // fall back to server-side proxy
  }
  return { data: null };
}

Prevention

When it happens

Trigger: Calling `fetch('https://api.other.com/...')` in a universal `+page.js` load where the API returns no `access-control-allow-origin` header, or one that doesn't match the current origin and isn't `*`.

Common situations: Third-party APIs without CORS support; API configured with a wrong origin (e.g. localhost:3000 vs localhost:5173); CDN/proxy stripping CORS headers; dev-to-prod origin mismatches.

Related errors


AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02). Data as JSON: /api/errors/e46e3bfa7398d4b0. Report an issue: GitHub.