sveltejs/kit · error · Error
Cannot redirect to ${JSON.stringify(location)} with `{ exter
Error message
Cannot redirect to ${JSON.stringify(location)} with `{ external: true }`. The `javascript:` and `data:` protocols must be explicitly listed in the `external` allowlist (prod: 'Cannot redirect to external URL unless explicitly allowed') What it means
Even with `{ external: true }`, SvelteKit blocks `javascript:` and `data:` URLs because redirecting to them is a code-injection/XSS vector. Such URLs can only be redirected to if they are explicitly listed in an `external` allowlist array, signaling deliberate intent.
Source
Thrown at packages/kit/src/exports/url.js:58
* @param {{ external?: boolean | string[] }} [options]
*/
export function validate_redirect_location(location, options) {
if (!is_external_location(location)) return;
const external = options?.external;
if (!external) {
throw new Error(
DEV
? `Cannot redirect to external URL ${JSON.stringify(location)}. ` +
'To redirect to an external URL, pass `{ external: true }` or an allowlist of permitted origins as the third argument to `redirect`'
: 'Cannot redirect to external URL unless explicitly allowed'
);
}
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'
);
}View on GitHub (pinned to 03f1687fe6)
Solutions
- Remove any `javascript:`/`data:` redirect targets — use regular `https://` or relative URLs.
- If genuinely required (rare), enumerate them in an allowlist: `redirect(302, loc, { external: ['javascript:myscheme'] })` (pattern: explicit allowed origins/schemes array).
- Sanitize input: reject or strip locations whose scheme is not `http:`/`https:` or a relative path.
- Treat any user path that produces these URLs as an attack attempt and fall back to a safe default redirect.
Example fix
// before
redirect(302, target, { external: true }); // target may be 'data:...'
// after
if (/^data:|^javascript:/i.test(target)) redirect(302, '/');
else redirect(302, target, { external: true }); Defensive patterns
Strategy: validation
Validate before calling
function isSafeRedirectTarget(loc) {
if (/^(javascript|data):/i.test(loc)) return false;
try { const u = new URL(loc, 'http://internal'); return !/^javascript:|^data:/i.test(u.protocol); }
catch { return false; }
}
if (!isSafeRedirectTarget(target)) redirect(302, '/'); Type guard
const isWebUrl = (s) => {
try { const u = new URL(s, 'http://internal'); return ['http:', 'https:'].includes(u.protocol); }
catch { return false; }
}; Try / catch
try {
redirect(302, target, { external: true });
} catch (e) {
if (String(e.message).includes('javascript:') || String(e.message).includes('data:')) {
redirect(302, '/');
} else throw e;
} Prevention
- Allowlist schemes: only http/https (or relative) targets.
- Reject any location starting with javascript: or data: outright.
- Log and drop suspicious redirect targets from user input.
- Pass an explicit origins array rather than `external: true` when possible.
When it happens
Trigger: Calling `redirect(302, 'javascript:alert(1)', { external: true })` or `redirect(302, 'data:text/html,...', { external: true })` — `true` is not enough; only `external: ['javascript:...', 'data:...']` permits these schemes.
Common situations: Passing user-supplied URLs straight through with `external: true` in a test harness or admin tool; accidentally forwarding a `data:` URL captured from a form or query parameter.
Related errors
- Cannot redirect to external URL ${JSON.stringify(location)}.
- Invalid status code
- Invalid redirect location ${JSON.stringify(location)}: this
- ${keypath} cannot be empty
- Each member of ${keypath} must start with '.' — saw '${exten
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/799bc7dfca56387b.
Report an issue: GitHub.