withastro/astro · error · AstroError
UnsupportedExternalRedirect
UnsupportedExternalRedirect
Error message
The destination URL in the external redirect from "${from}" to "${to}" is unsupported. What it means
UnsupportedExternalRedirect: a configured redirect's destination is a parseable URL that does not start with http:// or https://. Astro only permits external redirects over HTTP(S); other protocols (ftp://, mailto:, relative, or malformed scheme) are rejected at manifest build time.
Source
Thrown at packages/astro/src/core/routing/create-manifest.ts:542
const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic)
? `/${segments.map((segment) => segment[0].content).join('/')}`
: null;
const params = segments
.flat()
.filter((p) => p.dynamic)
.map((p) => p.content);
const route = joinSegments(segments);
let destination: string;
if (typeof to === 'string') {
destination = to;
} else {
destination = to.destination;
}
// check if the link starts with http or https; if not, throw an error
if (URL.canParse(destination) && !/^https?:\/\//.test(destination)) {
throw new AstroError({
...UnsupportedExternalRedirect,
message: UnsupportedExternalRedirect.message(from, destination),
});
}
const redirectRoute = routeMap.get(destination);
// If the source has dynamic params and the redirect will be prerendered,
// we need a valid redirectRoute to map them. Without it, the build will fail
// later with a misleading error. Catch this early and provide a clear error message.
if (
params.length > 0 &&
!redirectRoute &&
!URL.canParse(destination) &&
getPrerenderDefault(config)
) {
throw new AstroError({
...InvalidRedirectDestination,View on GitHub (pinned to d081033d5f)
Solutions
- Change the destination to start with http:// or https://.
- If the destination is a local path, drop the scheme and use a root-relative '/path'.
- Validate redirect destinations against /^https?:\/\// before deploying config.
Example fix
// before — astro.config.mjs
redirects: { '/old': 'ftp://files.example.com' }
// after
redirects: { '/old': 'https://files.example.com' } Defensive patterns
Strategy: validation
Validate before calling
function isSupportedExternalRedirect(dest: string): boolean {
return !URL.canParse(dest) || /^https?:\/\//.test(dest);
}
// validate redirect destinations in config before build Type guard
function isHttpUrl(value: string): boolean {
return /^https?:\/\//.test(value);
} Prevention
- Use only http(s):// or root-relative paths in config.redirects.
- Lint redirect destinations against /^https?:\/\// or a leading '/' in CI.
- Avoid protocol-relative '//host' URLs.
When it happens
Trigger: Setting redirects in astro.config to a destination like 'ftp://example.com', '//example.com', or a protocol-relative URL; using a string that URL.canParse accepts but lacks the http(s) scheme.
Common situations: Copying a non-http URL into config.redirects; protocol-relative URLs from legacy configs; accidentally prefixing with a wrong scheme; data-driven redirect config populated from a CMS.
Related errors
- FailedToFetchRemoteImageDimensions
- InvalidRedirectDestination
- MissingIndexForInternationalizationError
- EnvInvalidVariables
- maxDuration must be a positive number
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/82c233b5d40e0849.
Report an issue: GitHub.