mastra-ai/mastra · error · WebFetchError

Redirect target must use HTTP or HTTPS.

Error message

Redirect target must use HTTP or HTTPS.

What it means

When a 3xx response carries a Location header, requestUrl builds the absolute redirect target with new URL(location, url) and re-validates it through parseHttpUrl, which only accepts http: and https: schemes. If the redirect target is not HTTP(S) — e.g. a Location pointing to ftp:, file:, data:, or a malformed relative reference that yields a non-HTTP URL — the tool throws a WebFetchError instead of following it, blocking protocol-redirection attacks.

Source

Thrown at packages/core/src/tools/builtin/web-fetch.ts:223

          accept: 'text/html,text/plain,application/json,application/xml;q=0.9,*/*;q=0.8',
        },
        lookup: createLookup(),
        timeout: TIMEOUT_MS,
      },
      response => {
        void (async () => {
          const location = response.headers.location;

          if (location && response.statusCode && response.statusCode >= 300 && response.statusCode < 400) {
            response.resume();

            if (redirectsRemaining <= 0) {
              throw new WebFetchError(`Too many redirects. Maximum is ${MAX_REDIRECTS}.`);
            }

            const nextUrl = parseHttpUrl(new URL(location, url).toString());
            if (!nextUrl) {
              throw new WebFetchError('Redirect target must use HTTP or HTTPS.');
            }

            resolve(await requestUrl(nextUrl, redirectsRemaining - 1));
            return;
          }

          const { content, truncated } = await readBody(response);

          resolve({
            content,
            truncated,
            status: response.statusCode,
            statusText: response.statusMessage,
            contentType: Array.isArray(response.headers['content-type'])
              ? response.headers['content-type'][0]
              : (response.headers['content-type'] ?? null),
            url: url.toString(),
            ok: response.statusCode ? response.statusCode >= 200 && response.statusCode < 300 : false,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Inspect the response chain (curl -IL <url>) to see the non-HTTP Location value; if it's your server, fix the redirect to use https://.
  2. Fetch the intended HTTP(S) target directly instead of following the redirecting entry URL.
  3. Treat this on attacker-influenced URLs as malicious input: reject or sanitize the URL before passing it to webFetch.
  4. If a legacy ftp mirror is the real target, retrieve it outside the web-fetch tool (the tool is HTTP-only by design).

Example fix

// before
await webFetchTool.execute({ context: { url: 'https://legacy.example.com/downloads' } }); // Location: ftp://mirror...

// after: fetch an HTTP(S) endpoint directly
await webFetchTool.execute({ context: { url: 'https://mirror.example.com/downloads' } });
Defensive patterns

Strategy: try-catch

Validate before calling

// Only allow http(s) URLs, and check redirect targets the server might return
function isHttpUrl(raw: string): boolean {
  try {
    const u = new URL(raw);
    return u.protocol === 'http:' || u.protocol === 'https:';
  } catch { return false; }
}

Type guard

function isHttpScheme(u: URL): boolean {
  return u.protocol === 'http:' || u.protocol === 'https:';
}

Try / catch

try {
  await webFetchTool.execute({ context: { url } });
} catch (err) {
  if (err instanceof Error && err.message.includes('Redirect target must use HTTP or HTTPS')) {
    console.warn(`redirect to non-HTTP scheme from ${url}; refusing`);
  } else throw err;
}

Prevention

When it happens

Trigger: A server responding 3xx with a Location header whose scheme is not http/https (ftp:, file:, data:, javascript:), or a Location that cannot be parsed into an http(s) URL (e.g. an invalid relative reference or a URL with a disallowed scheme after base resolution).

Common situations: Malicious or misconfigured endpoints redirecting to non-HTTP schemes; legacy servers redirecting to ftp:// mirrors; attacker-controlled URLs in agent input attempting scheme-redirection SSRF or local-file reads.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/d8a3d581d0bd8e06. Report an issue: GitHub.