{"record":{"id":"94ffab72c8851d63","repo":"HMCL-dev/HMCL","slug":"malformed-response-n-text","errorCode":null,"errorMessage":"Malformed response\\n\" + text","messagePattern":"Malformed response\\\\n\" \\+ text","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorServer.java","lineNumber":157,"sourceCode":"    }\n\n    public String fetchMetadataResponse() throws IOException {\n        if (metadataResponse == null || !metadataRefreshed) {\n            refreshMetadata();\n        }\n        return getMetadataResponse().get();\n    }\n\n    public void refreshMetadata() throws IOException {\n        refreshMetadata(HttpRequest.GET(url).getString());\n    }\n\n    private void refreshMetadata(String text) throws IOException {\n        long timestamp = System.currentTimeMillis();\n        try {\n            setMetadataResponse(text, timestamp);\n        } catch (JsonParseException e) {\n            throw new IOException(\"Malformed response\\n\" + text, e);\n        }\n\n        metadataRefreshed = true;\n        LOG.info(\"authlib-injector server metadata refreshed: \" + url);\n        Platform.runLater(helper::invalidate);\n    }\n\n    private void setMetadataResponse(String metadataResponse, long metadataTimestamp) throws JsonParseException {\n        JsonObject response = GSON.fromJson(metadataResponse, JsonObject.class);\n        if (response == null) {\n            throw new JsonParseException(\"Metadata response is empty\");\n        }\n\n        synchronized (this) {\n            this.metadataResponse = metadataResponse;\n            this.metadataTimestamp = metadataTimestamp;\n\n            Optional<JsonObject> metaObject = tryCast(response.get(\"meta\"), JsonObject.class);","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/authlibinjector/AuthlibInjectorServer.java#L139-L175","documentation":"AuthlibInjectorServer.refreshMetadata parses the server's metadata response body; if JSON parsing fails it wraps the JsonParseException in an IOException \"Malformed response\\n\" + the raw text. This means the remote server did not return valid authlib-injector metadata JSON.","triggerScenarios":"Calling locateServer/refreshMetadata against a URL whose HTTP response body is not valid JSON (HTML error page, empty body, proxy interstitial, wrong service).","commonSituations":"Entering a non-authlib-injector URL (landing page or HTML status page); captive portals/proxies returning HTML; server returning 200 with an error page; truncated responses.","solutions":["Verify the URL points to a real authlib-injector (Yggdrasil) API root, not a website landing page","Inspect the raw response text (included in the exception) to see what the server returned","Retry when behind a captive portal or proxy, or use a different network","Check the server's status page; the instance may be down or misconfigured"],"exampleFix":"// before\nserver = AuthlibInjectorServer.locateServer(\"https://example.com/\"); // HTML page\n// after\nserver = AuthlibInjectorServer.locateServer(\"https://auth.server.example/api/yggdrasil\");","handlingStrategy":"try-catch","validationCode":"// optionally pre-check that the URL responds with JSON\nString body = httpGetString(url);\nif (body == null || body.isBlank() || !body.strip().startsWith(\"{\")) {\n    throw new IOException(\"Server did not return JSON metadata\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    AuthlibInjectorServer server = AuthlibInjectorServer.locateServer(url);\n} catch (IOException e) {\n    ui.showError(\"Server returned malformed metadata: \" + e.getMessage());\n}","preventionTips":["Enter the API root of an authlib-injector/Yggdrasil server, not a website","Log the response body included in the exception for diagnosis","Detect captive portals/proxies that return HTML","Retry metadata refresh on transient server failures"],"tags":["network","json","authlib-injector","minecraft"],"backgroundTag":"invalid-json-response","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}