{"record":{"id":"77c95bbeaef4cbac","repo":"n8n-io/n8n","slug":"maximum-number-of-redirects-maxredirects-exce","errorCode":null,"errorMessage":"Maximum number of redirects (${maxRedirects}) exceeded","messagePattern":"Maximum number of redirects \\((.+?)\\) exceeded","errorType":"exception","errorClass":"OperationalError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/backend-network/src/http/axios/redirect.ts","lineNumber":262,"sourceCode":"\n\tfor (let redirectCount = 0; ; redirectCount++) {\n\t\tconst response = await invokeAxios(config, policy.authSendImmediately);\n\t\tconst location = getRedirectLocation(response);\n\n\t\tif (!isRedirectStatus(response.status) || !location) {\n\t\t\tif (isRedirectStatus(response.status)) {\n\t\t\t\tthrowIfStatusRejected(response, baseValidateStatus);\n\t\t\t}\n\t\t\treturn response;\n\t\t}\n\n\t\t// This response is a redirect we will not return.\n\t\t// Release its body (a no-op for buffered bodies, frees the socket for streamed ones)\n\t\t// before we either stop or follow.\n\t\tdiscardResponseBody(response);\n\n\t\tif (redirectCount >= maxRedirects) {\n\t\t\tthrow new OperationalError(`Maximum number of redirects (${maxRedirects}) exceeded`);\n\t\t}\n\n\t\tconst nextUrl = resolveRedirectUrl(location, currentUrl);\n\t\tthrowIfDomainNotAllowed(nextUrl, policy.allowedDomains);\n\t\tawait validateUrlSsrf(nextUrl, policy.ssrf);\n\n\t\tconfig = prepareHop(\n\t\t\tbuildRedirectHopConfig(config, response.status, originalUrl, nextUrl, policy),\n\t\t);\n\t\tcurrentUrl = nextUrl;\n\t}\n}\n","sourceCodeStart":244,"sourceCodeEnd":275,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/backend-network/src/http/axios/redirect.ts#L244-L275","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst res = await followSsrfRedirects(config, policy);\n\n// after - allow a longer legitimate chain\nconst res = await followSsrfRedirects(\n  { ...config, maxRedirects: 21 },\n  policy,\n);","handlingStrategy":"try-catch","validationCode":"// Cap the redirect budget deliberately per call\nconst maxRedirects = config.maxRedirects ?? 5;","typeGuard":"import { OperationalError } from 'n8n-workflow';\nconst isTooManyRedirects = (e: unknown): boolean =>\n  e instanceof OperationalError && /Maximum number of redirects/.test(e.message);","tryCatchPattern":"try {\n  const res = await followSsrfRedirects(config, policy);\n} catch (e) {\n  if (e instanceof OperationalError && /Maximum number of redirects/.test(e.message)) {\n    // likely a redirect loop — log the chain and surface 'upstream misconfigured'\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["http","redirect","ssrf","redirect-loop","backend-network"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}