{"record":{"id":"952816f6820ef2ae","repo":"dgtlmoon/changedetection.io","slug":"too-many-redirects","errorCode":null,"errorMessage":"Too many redirects","messagePattern":"Too many redirects","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"changedetectionio/content_fetchers/requests.py","lineNumber":126,"sourceCode":"            current_url = url\n            for _ in range(10):\n                if not r.is_redirect:\n                    break\n                location = r.headers.get('Location', '')\n                redirect_url = urljoin(current_url, location)\n                if not allow_iana_restricted:\n                    if is_url_private_or_parser_confused(redirect_url):\n                        raise Exception(f\"Redirect blocked: '{redirect_url}' resolves to a private/reserved IP address \"\n                                        f\"or contains a parser-differential payload.\")\n                current_url = redirect_url\n                r = session.request('GET', redirect_url,\n                                    headers=request_headers,\n                                    timeout=timeout,\n                                    proxies=proxies,\n                                    verify=False,\n                                    allow_redirects=False)\n            else:\n                raise Exception(\"Too many redirects\")\n\n        except Exception as e:\n            msg = str(e)\n            if proxies and 'SOCKSHTTPSConnectionPool' in msg:\n                msg = f\"Proxy connection failed? {msg}\"\n            raise Exception(msg) from e\n\n        # If the response did not tell us what encoding format to expect, Then use chardet to override what `requests` thinks.\n        # For example - some sites don't tell us it's utf-8, but return utf-8 content\n        # This seems to not occur when using webdriver/selenium, it seems to detect the text encoding more reliably.\n        # https://github.com/psf/requests/issues/1604 good info about requests encoding detection\n        if not is_binary:\n            # Don't run this for PDF (and requests identified as binary) takes a _long_ time\n            if not r.headers.get('content-type') or not 'charset=' in r.headers.get('content-type'):\n                # For XML/RSS feeds, check the XML declaration for encoding attribute\n                # This is more reliable than chardet which can misdetect UTF-8 as MacRoman\n                content_type = r.headers.get('content-type', '').lower()\n                if 'xml' in content_type or 'rss' in content_type:","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/dgtlmoon/changedetection.io/blob/5d9c7c6da76340597243e8163c4f2439237fa0e8/changedetectionio/content_fetchers/requests.py#L108-L144","documentation":"The requests fetcher caps manual redirect following; when the loop exits without a non-redirect response (redirect chain exceeds the attempt limit) it raises 'Too many redirects'.","triggerScenarios":"URL whose redirect chain never terminates — A→B→A loops, cookie-less client stuck on a consent/redirect page, or server always answering 30x.","commonSituations":"Site requiring cookies/headers the fetcher lacks so it loops on the same redirect; misconfigured server; intentional redirect loop.","solutions":["Trace the chain: curl -IL <url> and look for the loop point","Add required cookies/headers or a User-Agent the site expects","If the loop is on the server side, watch the final destination URL directly"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import requests\nr = requests.get(url, allow_redirects=False, timeout=10)\nseen = set()\nwhile r.is_redirect:\n    nxt = r.headers['Location']\n    if nxt in seen:\n        raise ConfigError('redirect loop detected — fix watch URL')\n    seen.add(nxt)\n    r = requests.get(nxt, allow_redirects=False, timeout=10)","typeGuard":null,"tryCatchPattern":"try:\n    fetcher.run()\nexcept Exception as e:\n    if 'Too many redirects' in str(e):\n        trace_chain(url)  # find the loop and update watch to final URL","preventionTips":["Watch the final destination URL, not redirecting front doors","Send the session cookies/headers the site expects to break consent loops","Detect redirect loops in config before scheduling checks"],"tags":["redirect-loop","requests","http"],"backgroundTag":"redirect-loop","analyzedSha":"5d9c7c6da76340597243e8163c4f2439237fa0e8","analyzedAt":"2026-08-27T19:41:16.067Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}