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
- Configure the remote API to send `Access-Control-Allow-Origin: <your origin>` or `*`
- Proxy the request through your own SvelteKit `+server.js` endpoint (same-origin, no CORS needed)
- 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
- Check CORS headers of third-party APIs before fetching them in universal loads
- Prefer proxying external APIs through your own +server.js endpoints
- Ensure dev and prod origins are both allowed by the remote API
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
- response.status is not a number. value: "${response.status}"
- Loading ${url} using `window.fetch`. For best results, use t
- ${node.server_id}: Calling `event.fetch(...)` in a promise h
- read(...) failed: could not fetch ${url} (${response.status}
- exports is not available in dev mode
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/e46e3bfa7398d4b0.
Report an issue: GitHub.