n8n-io/n8n · error · OperationalError
Maximum number of redirects (${maxRedirects}) exceeded
Error message
Maximum number of redirects (${maxRedirects}) exceeded What it means
OperationalError thrown by followSsrfRedirects when redirectCount reaches maxRedirects (default MAX_REDIRECTS_DEFAULT, overridable via initialConfig.maxRedirects). Each 3xx hop increments redirectCount; if the chain does not terminate within the budget, the loop aborts to prevent redirect cycles.
Source
Thrown at packages/@n8n/backend-network/src/http/axios/redirect.ts:262
for (let redirectCount = 0; ; redirectCount++) {
const response = await invokeAxios(config, policy.authSendImmediately);
const location = getRedirectLocation(response);
if (!isRedirectStatus(response.status) || !location) {
if (isRedirectStatus(response.status)) {
throwIfStatusRejected(response, baseValidateStatus);
}
return response;
}
// This response is a redirect we will not return.
// Release its body (a no-op for buffered bodies, frees the socket for streamed ones)
// before we either stop or follow.
discardResponseBody(response);
if (redirectCount >= maxRedirects) {
throw new OperationalError(`Maximum number of redirects (${maxRedirects}) exceeded`);
}
const nextUrl = resolveRedirectUrl(location, currentUrl);
throwIfDomainNotAllowed(nextUrl, policy.allowedDomains);
await validateUrlSsrf(nextUrl, policy.ssrf);
config = prepareHop(
buildRedirectHopConfig(config, response.status, originalUrl, nextUrl, policy),
);
currentUrl = nextUrl;
}
}
View on GitHub (pinned to 5ac6606e81)
Solutions
- Inspect the captured chain (log each currentUrl/Location) to find the loop point.
- Fix the server-side redirect rule that creates the cycle.
- If a long legitimate chain is expected, raise initialConfig.maxRedirects deliberately.
- Verify cookies/auth are being sent so the server stops bouncing to a login page.
Example fix
// before
const res = await followSsrfRedirects(config, policy);
// after - allow a longer legitimate chain
const res = await followSsrfRedirects(
{ ...config, maxRedirects: 21 },
policy,
); Defensive patterns
Strategy: try-catch
Validate before calling
// Cap the redirect budget deliberately per call const maxRedirects = config.maxRedirects ?? 5;
Type guard
import { OperationalError } from 'n8n-workflow';
const isTooManyRedirects = (e: unknown): boolean =>
e instanceof OperationalError && /Maximum number of redirects/.test(e.message); Try / catch
try {
const res = await followSsrfRedirects(config, policy);
} catch (e) {
if (e instanceof OperationalError && /Maximum number of redirects/.test(e.message)) {
// likely a redirect loop — log the chain and surface 'upstream misconfigured'
}
throw e;
} Prevention
- Log each hop URL to detect A<->B loops quickly.
- Fix server-side redirect rules rather than raising maxRedirects without reason.
- Send cookies/auth correctly so auth flows do not bounce to login indefinitely.
When it happens
Trigger: The target URL returns a chain of 3xx responses longer than maxRedirects. Common shapes: A->B->A ping-pong, a long sequential chain, or a final hop that itself keeps redirecting. The check fires before following the (maxRedirects+1)th hop.
Common situations: A misconfigured login/auth flow that keeps redirecting; a CDN edge loop; an erroneously configured trailing-slash rewrite rule alternating between two URLs; a server that redirects to itself with a session cookie it never accepts.
Related errors
- Request failed with status code ${response.status}
- Invalid redirect location received from server: ${location}
- SSL Issue: consider using the 'Ignore SSL issues' option
- Failed to list ${provider} models (status ${response.status}
- Webhook URL must use HTTPS. Got: ${url.protocol}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/77c95bbeaef4cbac.
Report an issue: GitHub.