{"record":{"id":"46cabd8d32201433","repo":"jhy/jsoup","slug":"too-many-redirects-occurred-trying-to-load-url-s","errorCode":null,"errorMessage":"Too many redirects occurred trying to load URL %s","messagePattern":"Too many redirects occurred trying to load URL (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/jsoup/helper/HttpConnection.java","lineNumber":1204,"sourceCode":"        }\n\n        // set up url, method, header, cookies\n        void prepareResponse(Map<String, List<String>> resHeaders, HttpConnection.@Nullable Response previousResponse) throws IOException {\n            processResponseHeaders(resHeaders); // includes cookie key/val read during header scan\n            CookieUtil.storeCookies(req, this, url, resHeaders); // add set cookies to cookie store\n\n            if (previousResponse != null) { // was redirected\n                // map previous response cookies into this response cookies() object\n                for (Map.Entry<String, String> prevCookie : previousResponse.cookies().entrySet()) {\n                    if (!hasCookie(prevCookie.getKey()))\n                        cookie(prevCookie.getKey(), prevCookie.getValue());\n                }\n                previousResponse.safeClose();\n\n                // enforce too many redirects:\n                numRedirects = previousResponse.numRedirects + 1;\n                if (numRedirects >= MAX_REDIRECTS)\n                    throw new IOException(String.format(\"Too many redirects occurred trying to load URL %s\", previousResponse.url()));\n            }\n        }\n\n        void processResponseHeaders(Map<String, List<String>> resHeaders) {\n            for (Map.Entry<String, List<String>> entry : resHeaders.entrySet()) {\n                String name = entry.getKey();\n                if (name == null)\n                    continue; // http/1.1 line\n\n                List<String> values = entry.getValue();\n                for (String value : values) {\n                    addHeader(name, fixHeaderEncoding(value));\n                }\n            }\n        }\n\n        /**\n         Servers may encode response headers in UTF-8 instead of RFC defined 8859. The JVM decodes the headers (before we see them) as 8859, which can lead to mojibake data.","sourceCodeStart":1186,"sourceCodeEnd":1222,"githubUrl":"https://github.com/jhy/jsoup/blob/9851ac5d9c576c6888910b5a51a2362bbc978959/src/main/java/org/jsoup/helper/HttpConnection.java#L1186-L1222","documentation":"Jsoup caps redirect chains at MAX_REDIRECTS to protect against infinite or circular redirect loops. When following redirects exceeds that cap, execute() throws IOException with this message, including the URL of the last response. It mirrors the same safeguard in browsers and HTTP clients.","triggerScenarios":"A server redirect loop (A -> B -> A), misconfigured load balancers bouncing requests, or cookies/auth never accepted so the server keeps redirecting to a login page that redirects back.","commonSituations":">20-deep redirect chains; www/non-www or http/https rewrite loops; login redirects that fail because session cookies are not persisted; geo/consent walls that never settle.","solutions":["Open the URL in a browser or curl -IL to find and fix the redirect loop server-side","Manually follow redirects with followRedirects(false) and stop after detecting a repeated URL","Send required cookies/auth headers so the server stops redirecting to login","If legitimate deep chains exist, resend from the last Location with your own counter"],"exampleFix":"// before\nDocument doc = Jsoup.connect(url).get(); // IOException on loop\n// after\nConnection.Response res = Jsoup.connect(url).followRedirects(false).execute();\nSet<String> seen = new HashSet<>();\nwhile (res.statusCode() / 100 == 3 && seen.add(res.url().toString())) {\n    res = Jsoup.connect(res.header(\"Location\")).followRedirects(false).execute();\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { doc = Jsoup.connect(url).get(); } catch (IOException e) { if (e.getMessage().startsWith(\"Too many redirects\")) { /* flag URL as looping */ } }","preventionTips":["Manually follow redirects with a seen-URL set to detect loops early","Persist session cookies so login redirects complete","Fix server-side rewrite loops surfaced by this error"],"tags":["java","jsoup","http","redirect-loop"],"backgroundTag":"http-error-response","analyzedSha":"9851ac5d9c576c6888910b5a51a2362bbc978959","analyzedAt":"2026-09-08T15:22:04.931Z","contentChangedAt":"2026-09-08T15:22:04.931Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}