sveltejs/kit · error · Error
Cannot redirect to ${JSON.stringify(location)}: URL origin i
Error message
Cannot redirect to ${JSON.stringify(location)}: URL origin is not included in the `external` allowlist (prod: 'Cannot redirect to external URL unless explicitly allowed') What it means
SvelteKit's `redirect()` only allows redirecting to absolute external URLs when the `external` option explicitly allows them. When `external` is an array, each target origin is matched against the allowlist entries; a URL whose origin matches no entry throws this error (a generic message in production). This prevents open-redirect vulnerabilities by default.
Source
Thrown at packages/kit/src/exports/url.js:71
);
}
if (external === true) {
if (is_javascript_location(location)) {
throw new Error(
DEV
? `Cannot redirect to ${JSON.stringify(location)} with \`{ external: true }\`. ` +
'The `javascript:` and `data:` protocols must be explicitly listed in the `external` allowlist'
: 'Cannot redirect to external URL unless explicitly allowed'
);
}
return;
}
if (Array.isArray(external)) {
if (!external.some((allowed) => matches_external_allowlist_entry(location, allowed))) {
throw new Error(
DEV
? `Cannot redirect to ${JSON.stringify(location)}: URL origin is not included in the \`external\` allowlist`
: 'Cannot redirect to external URL unless explicitly allowed'
);
}
return;
}
throw new Error(
DEV
? '`redirect` options.external must be `true` or an array of allowed origins'
: 'Invalid redirect options.external value'
);
}
View on GitHub (pinned to 03f1687fe6)
Solutions
- Add the target origin to the `external` allowlist array in the redirect call
- Redirect with a relative URL if the target is on the same origin
- Pass `external: true` if any external URL is intentionally allowed
- Verify the URL being built at runtime — the origin may come from user input or an env var you didn't expect
Example fix
// before
redirect(302, `https://accounts.google.com/o/oauth2/auth?...`, { external: ['https://auth.example.com'] });
// after
redirect(302, `https://accounts.google.com/o/oauth2/auth?...`, { external: ['https://auth.example.com', 'https://accounts.google.com'] }); Defensive patterns
Strategy: validation
Validate before calling
const url = new URL(location, event.url.origin);
const allowed = ['https://auth.example.com', 'https://accounts.google.com'];
if (url.origin !== event.url.origin && !allowed.includes(url.origin)) {
throw new Error(`Refusing redirect to non-allowlisted origin: ${url.origin}`);
} Type guard
function isAllowedExternal(location, allowlist) {
try {
const url = new URL(location);
return allowlist.some((a) => new URL(a).origin === url.origin);
} catch {
return false;
}
} Try / catch
try {
redirect(302, target, { external: allowlist });
} catch (err) {
if (/external allowlist/.test(err.message)) {
throw redirect(302, '/fallback');
}
throw err;
} Prevention
- Keep the external allowlist in one shared config module used by every redirect
- Never build redirect targets from raw user input without validating the origin
- Prefer relative redirects for same-origin navigation
- Log rejected redirect attempts to catch allowlist gaps early
When it happens
Trigger: Calling `redirect(302, 'https://evil.com/path', { external: ['https://good.com'] })` or any absolute URL to an origin not listed in the `external` allowlist array passed to `redirect` (or the underlying `validate_redirect_location`).
Common situations: Redirecting to OAuth/IDP callbacks, payment providers, or another subdomain after login; an allowlist that was written for one environment (staging origin) but the code now redirects to a production origin.
Related errors
- Cannot redirect to external URL ${JSON.stringify(location)}.
- Cannot redirect to ${JSON.stringify(location)} with `{ exter
- Multiple values provided for ${name} header where only one e
- The ${protocol_header} header specified ${protocol} which is
- The ${port_header} header specified ${port} which is an inva
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/2944be8007e4eb77.
Report an issue: GitHub.