{"record":{"id":"103b6532f9c4b03f","repo":"octobercms/october","slug":"system-lang-server-response-invalid","errorCode":"system::lang.server.response_invalid","errorMessage":"Invalid response from the server.","messagePattern":"Invalid response from the server\\.","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"error","filePath":"modules/system/classes/updatemanager/HasGatewayAccess.php","lineNumber":62,"sourceCode":"        if ($result->status() === 404) {\n            throw new ApplicationException(Lang::get('system::lang.server.response_not_found'));\n        }\n\n        if ($result->status() !== 200) {\n            throw new ApplicationException(\n                strlen($contents)\n                ? $contents\n                : Lang::get('system::lang.server.response_empty')\n            );\n        }\n\n        $resultData = false;\n\n        try {\n            $resultData = @json_decode($contents, true);\n        }\n        catch (Exception $ex) {\n            throw new ApplicationException(Lang::get('system::lang.server.response_invalid'));\n        }\n\n        if ($resultData === false || (is_string($resultData) && !strlen($resultData))) {\n            throw new ApplicationException(Lang::get('system::lang.server.response_invalid'));\n        }\n\n        return $resultData;\n    }\n\n    /**\n     * requestServerFile downloads a file from the update server.\n     * @param string $uri\n     * @param string $fileCode\n     * @param array $postData\n     */\n    public function requestServerFile($uri, $fileCode, $postData = [])\n    {\n        $filePath = $this->getFilePath($fileCode);","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/system/classes/updatemanager/HasGatewayAccess.php#L44-L80","documentation":"After a 200 response, requestServerData() decodes the gateway body with @json_decode; the catch around it throws 'Invalid response from the server' (system::lang.server.response_invalid) if decoding raises. This indicates the update server returned something that is not valid JSON — an HTML error page, a serialized blob, or a truncated body. It is the 'server answered but spoke the wrong protocol' branch of the updater's response validation.","triggerScenarios":"Gateway returns 200 with HTML (captive portal, login page, proxy interstitial), partially downloaded body, or BOM/prefix noise before the JSON; any update/marketplace request going through requestServerData().","commonSituations":"Captive Wi-Fi / hotel portal intercepting HTTPS; a custom update server returning rendered pages on some routes; response compression or charset issues corrupting the body; ISP-level content rewriting.","solutions":["Capture the raw response (curl the same endpoint) and inspect what is actually returned instead of JSON","If a captive portal or proxy injects HTML, fix the network path or proxy exclusions for the gateway host","For custom gateways, ensure every endpoint the updater hits emits application/json only","Verify the body isn't truncated by TLS inspection or output compression middleware"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $response = \\System\\Classes\\UpdateManager::instance()->requestServerData($uri, $postData);\n} catch (\\October\\Rain\\Exception\\ApplicationException $ex) {\n    if (str_contains($ex->getMessage(), 'Invalid response')) {\n        // gateway spoke non-JSON (captive portal/proxy) — log the context, don't retry blindly\n        Log::warning('Update gateway returned non-JSON payload', ['uri' => $uri]);\n    }\n    throw $ex;\n}","preventionTips":["Verify server egress reaches the gateway cleanly (no captive portals/WAF interstitials)","For custom gateways, assert Content-Type: application/json on every updater route in tests","Keep a curl-based health check for gateway endpoints in your monitoring"],"tags":["octobercms","updates","network","json","invalid-response"],"backgroundTag":"invalid-json-response","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}