mastra-ai/mastra · error · WebFetchError

Too many redirects. Maximum is ${MAX_REDIRECTS}.

Error message

Too many redirects. Maximum is ${MAX_REDIRECTS}.

What it means

requestUrl follows HTTP 3xx redirects manually, up to MAX_REDIRECTS hops, decrementing redirectsRemaining each time. When a redirect response arrives and no redirect budget remains, the tool throws a WebFetchError because unbounded redirect following is both a hang/infinite-loop risk and an SSRF vector (long chains can be steered toward internal addresses).

Source

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

    const request = requestModule.request(
      url,
      {
        headers: {
          'user-agent': 'Mastra Web Fetch Tool/1.0',
          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,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Resolve the final URL yourself and pass it directly (e.g. curl -ILs <url> to find the terminal URL, or use a URL-expansion service once).
  2. Break redirect loops: fix the target server's redirect configuration (avoid http<->https or trailing-slash loops).
  3. If the content genuinely needs many hops, fetch the intermediate hop(s) with separate webFetch calls.
  4. For legitimate deep chains, raise MAX_REDIRECTS in a fork/patch of the tool — but confirm each hop stays on public hosts, since the limit is also a safety guard.

Example fix

// before
await webFetchTool.execute({ context: { url: 'https://bit.ly/abc123' } }); // 6+ hop chain

// after: resolve first, then fetch the terminal URL
await webFetchTool.execute({ context: { url: 'https://example.com/final/article' } });
Defensive patterns

Strategy: try-catch

Validate before calling

// Resolve redirect chains ahead of time and fetch only the terminal URL
async function resolveFinalUrl(url: string, max = 5): Promise<string> {
  let current = url;
  for (let i = 0; i < max; i++) {
    const res = await fetch(current, { redirect: 'manual', method: 'HEAD' });
    if (res.status < 300 || res.status >= 400) return current;
    const loc = res.headers.get('location');
    if (!loc) return current;
    current = new URL(loc, current).toString();
  }
  throw new Error('exceeds webFetch redirect limit');
}

Try / catch

try {
  await webFetchTool.execute({ context: { url } });
} catch (err) {
  if (err instanceof Error && /Too many redirects/.test(err.message)) {
    // resolve the chain manually and retry once with the terminal URL
    const finalUrl = await resolveFinalUrl(url);
    return webFetchTool.execute({ context: { url: finalUrl } });
  } else throw err;
}

Prevention

When it happens

Trigger: Fetching a URL that redirects more than MAX_REDIRECTS times: redirect chains, loops (A -> B -> A), cookie/auth flows redirecting repeatedly, short-link services stacked multiple deep, or misconfigured servers emitting endless 302s.

Common situations: Shortened URLs (bit.ly chains) embedded in agent prompts; expired sessions that keep redirecting to a login page that redirects back; misconfigured hosting where http->https->http loops.

Related errors


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