JuliusBrussee/caveman · error · TypeError
fetch failed: too many redirects
Error message
fetch failed: too many redirects
What it means
The proxy-aware fetch follows 3xx redirects automatically (for statuses 301/302/303/307/308 with a Location header) but caps the chain at MAX_REDIRECTS. When the server keeps redirecting past that limit, this TypeError aborts the request.
Source
Thrown at packages/cli/src/proxy-fetch.ts:352
headers,
body: buffered,
signal: request.signal ?? null,
};
let hop = resolveProxyUrl(current.url, env);
for (let redirects = 0; ; redirects += 1) {
const response = hop ? await sendThroughProxy(current, hop) : await baseFetch(current.url, {
method: current.method,
headers: current.headers as HeadersInit,
body: asBodyInit(current.body),
signal: current.signal,
redirect: "manual",
});
const location = response.headers.get("location");
const redirectable = [301, 302, 303, 307, 308].includes(response.status);
if (!redirectable || !location || request.redirect === "manual") return response;
if (redirects >= MAX_REDIRECTS) throw new TypeError("fetch failed: too many redirects");
if (request.redirect === "error") throw new TypeError("fetch failed: unexpected redirect");
const next = new URL(location, current.url);
const method = nextMethod(response.status, current.method);
const bodyDropped = method !== current.method;
void response.body?.cancel();
current = {
method,
url: next,
headers: redirectedHeaders(current.headers, current.url, next, bodyDropped),
body: bodyDropped ? null : current.body,
signal: current.signal,
};
hop = resolveProxyUrl(next, env);
}
} as typeof fetch;
}
View on GitHub (pinned to 5184b3d11a)
Solutions
- Fix the server-side redirect loop (check the Location targets and rewrite rules).
- Hit the final target URL directly to confirm the chain length: `curl -IL <url>`.
- Ensure cookies/auth headers needed by the redirect target are sent (redirects often drop credentials cross-origin).
- Check whether the proxy rewrites or re-redirects responses; bypass the proxy for that host (NO_PROXY).
- If the app must follow longer chains, raise MAX_REDIRECTS in proxy-fetch.ts or pass redirect: "manual" and handle hops yourself.
Example fix
// before
await fetch("http://old.example.com/loop"); // redirects forever
// after
const res = await fetch("https://new.example.com/final-target"); // call the canonical URL directly Defensive patterns
Strategy: try-catch
Type guard
function isTooManyRedirects(e: unknown): boolean { return e instanceof TypeError && e.message.includes("too many redirects"); } Try / catch
try {
const res = await fetch(url);
} catch (e) {
if (e instanceof TypeError && e.message.includes("too many redirects")) {
console.error(`Redirect loop at ${url}; try the canonical URL or bypass the proxy`);
} else throw e;
} Prevention
- Curl -IL your endpoints to confirm sane redirect chains (1 hop max).
- Avoid http->https or trailing-slash loops in server config.
- Send required cookies/auth headers so authenticated redirects resolve in one hop.
- Add hosts with redirect quirks to NO_PROXY if the proxy amplifies loops.
When it happens
Trigger: A fetch through createProxyAwareFetch receives more than MAX_REDIRECTS consecutive redirect responses — typically a redirect loop (A -> B -> A) or an extremely long redirect chain.
Common situations: Misconfigured server rewriting http->http or cookie-dependent redirects (redirect requires a session cookie the client isn't sending through the proxy); auth-gated URLs bouncing between login endpoints; proxy intercepting and re-redirecting each hop.
Related errors
- fetch failed: unexpected redirect
- tool search failed with HTTP ${response.status}
- device authorization failed: HTTP ${codeResponse.status}
- AbortError
- cave_sandbox_network_egress_unbounded
AI-assisted analysis of JuliusBrussee/caveman@5184b3d11a (2026-08-31).
Data as JSON: /api/errors/f7e11176f50ebf7f.
Report an issue: GitHub.