{"record":{"id":"360394dfccd00526","repo":"HMCL-dev/HMCL","slug":"too-much-redirects-360394","errorCode":null,"errorMessage":"Too much redirects","messagePattern":"Too much redirects","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/NetworkUtils.java","lineNumber":334,"sourceCode":"int code = conn.getResponseCode();\nif (code >= 300 && code <= 308 && code != 306 && code != 304) {\n    String newURL = conn.getHeaderField(\"Location\");\n    conn.disconnect();\n\n    if (redirect > 20) {\n        throw new IOException(\"Too much redirects\");\n    }\n\n    WebURL redirectedUrl = WebURL.of(conn.getURL()).resolve(newURL);\n    HttpURLConnection redirected = (HttpURLConnection) redirectedUrl.toURL().openConnection();\n    properties.forEach((key, value) -> value.forEach(element -> redirected.addRequestProperty(key, element)));\n    injectApiKey(redirectedUrl, redirected);\n    redirected.setRequestMethod(method);\n    conn = redirected;\n    ++redirect;\n} else {\n    break;\n}","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/NetworkUtils.java#L316-L352","documentation":"resolveConnection follows HTTP redirects manually (3xx-308 except 306/304) and aborts with this IOException once more than 20 hops occur. A redirect loop or an excessively long redirect chain on the target server is the usual cause.","triggerScenarios":"GET/download requests to a URL whose server redirects in a loop (A -> B -> A), or chains of more than 20 hops; cookies/sessions lost on each hop causing repeated redirects.","commonSituations":"Mirror URLs behind misconfigured load balancers; login-gated download endpoints endlessly redirecting to a login page; CDN misroutes after a site migration.","solutions":["Check the URL for a redirect loop (e.g. pointing to itself)","Try a mirror or alternate download source for the resource"],"exampleFix":"// before\nurl = \"http://example.com/download\"; // redirects to itself via https hop chain\n// after\nurl = \"https://example.com/download\"; // final destination, no redirects","handlingStrategy":"retry","validationCode":"int redirects = 0;\nHttpURLConnection c = (HttpURLConnection) url.openConnection();\nwhile ((c.getResponseCode() >= 300 && c.getResponseCode() <= 308) && ++redirects <= 20)\n    c = (HttpURLConnection) new URL(c.getHeaderField(\"Location\")).openConnection();\nif (redirects > 20) throw new IOException(\"redirect loop\");","typeGuard":null,"tryCatchPattern":"try {\n    NetworkUtils.doGet(url);\n} catch (IOException e) {\n    if (e.getMessage().equals(\"Too much redirects\")) {\n        // switch to another mirror / final https URL\n    } else throw e;\n}","preventionTips":["Use final https:// URLs directly instead of chained redirectors","Test URL chains with curl -IL before adding mirrors","Avoid login-gated endpoints for automated downloads","Keep session/cookie handling consistent across hops"],"tags":["network","http","redirect"],"backgroundTag":"http-error-response","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}