{"record":{"id":"dcb590a07186aba9","repo":"HMCL-dev/HMCL","slug":"redirected-to-an-empty-location","errorCode":null,"errorMessage":"Redirected to an empty location","messagePattern":"Redirected to an empty location","errorType":"exception","errorClass":"java.io.IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/task/FetchTask.java","lineNumber":357,"sourceCode":"                            if (DigestUtils.isSha1Digest(bmclapiHash)) {\n                                Optional<Path> cache = repository.checkExistentFile(null, \"SHA-1\", bmclapiHash);\n                                if (cache.isPresent()) {\n                                    useCachedResult(cache.get());\n                                    LOG.info(\"Using cached file for \" + NetworkUtils.dropQuery(uri));\n                                    return;\n                                }\n                            }\n\n                            if (responseCode >= 300 && responseCode <= 308 && responseCode != 306 && responseCode != 304) {\n                                if (redirects == null) {\n                                    redirects = new ArrayList<>();\n                                } else if (redirects.size() >= 20) {\n                                    throw new IOException(\"Too much redirects\");\n                                }\n\n                                String location = connection.getHeaderField(\"Location\");\n                                if (StringUtils.isBlank(location))\n                                    throw new IOException(\"Redirected to an empty location\");\n\n                                URI target = currentURI.resolve(NetworkUtils.encodeLocation(location));\n                                redirects.add(target);\n\n                                if (!NetworkUtils.isHttpUri(target))\n                                    throw new IOException(\"Redirected to not http URI: \" + target);\n\n                                currentURI = target;\n                            } else {\n                                keepConnection = true;\n                                break;\n                            }\n                        } finally {\n                            if (!keepConnection && connection != null) {\n                                closeHttpConnection(connection);\n                                connection = null;\n                            }\n                        }","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/task/FetchTask.java#L339-L375","documentation":"When FetchTask.downloadHttp() receives a redirect response, it reads the 'Location' header to build the next URI. This IOException is thrown when the Location header is missing or blank, so the redirect target cannot be determined.","triggerScenarios":"A server returns 3xx (301/302/307/308) without a valid Location header — a malformed redirect from a misconfigured server, proxy, or load balancer.","commonSituations":"Buggy reverse proxies or health-check endpoints responding with redirect codes but no Location; custom server implementations that set status codes without headers.","solutions":["Fix or bypass the misconfigured server sending redirects without Location","Use the final direct URL instead of the redirecting endpoint","Test with curl -I to confirm the malformed response before contacting the server admin","Catch the IOException and fall back to an alternative mirror"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"HttpURLConnection c = (HttpURLConnection) uri.toURL().openConnection();\nc.setInstanceFollowRedirects(false);\nif ((c.getResponseCode() / 100) == 2 && c.getHeaderField(\"Location\") != null)\n    throw new IllegalStateException(\"Malformed redirect (no Location) from \" + uri.getHost());","typeGuard":null,"tryCatchPattern":"try {\n    fetchTask.run();\n} catch (IOException e) {\n    if (e.getMessage().contains(\"empty location\")) failoverToMirror(uri);\n    else throw e;\n}","preventionTips":["Health-check mirror endpoints for well-formed redirects","Maintain a mirror list and rotate on malformed responses","Report broken redirecting servers to their operators"],"tags":["http","redirect","network"],"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"}