{"record":{"id":"30557c25dc8ff781","repo":"wtfutil/wtf","slug":"pi-hole-server-failed-to-respond-s","errorCode":null,"errorMessage":" Pi-hole server failed to respond\n %s","messagePattern":" Pi-hole server failed to respond\n (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/pihole/client.go","lineNumber":336,"sourceCode":"\t}\n\n\tdefer func() {\n\t\t_ = resp.Body.Close()\n\t}()\n\n\tif resp.StatusCode >= http.StatusBadRequest {\n\t\treturn fmt.Errorf(\" failed to retrieve version from Pi-hole server\\n http status code: %d\",\n\t\t\tresp.StatusCode)\n\t}\n\n\tvar vResp struct {\n\t\tVersion int `json:\"version\"`\n\t}\n\n\tvar rBody []byte\n\n\tif rBody, err = io.ReadAll(resp.Body); err != nil {\n\t\treturn fmt.Errorf(\" Pi-hole server failed to respond\\n %s\", parseError(err))\n\t}\n\n\tif err = json.Unmarshal(rBody, &vResp); err != nil {\n\t\treturn fmt.Errorf(\" invalid response returned from Pi-hole Server\\n %s\", parseError(err))\n\t}\n\n\tif vResp.Version != 3 {\n\t\treturn fmt.Errorf(\" only Pi-hole API version 3 is supported\\n version %d was detected\", vResp.Version)\n\t}\n\n\treturn err\n}\n\nfunc (widget *Widget) adblockSwitch(action string) {\n\tvar req *http.Request\n\n\tvar url *url2.URL\n\turl, _ = url2.Parse(widget.settings.apiUrl)","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/pihole/client.go#L318-L354","documentation":"checkServer reads the response body of the version probe. If io.ReadAll fails (connection dropped mid-response, read timeout, premature close), the library reports that the Pi-hole server failed to respond.","triggerScenarios":"io.ReadAll(resp.Body) returns an error in checkServer while reading the '<apiUrl>?version' response.","commonSituations":"Unstable network to the Pi-hole host, server closing the connection mid-transfer, proxy timing out the upstream, or TLS interruptions.","solutions":["Retry the request; if intermittent, check network stability between client and Pi-hole","Inspect reverse proxy timeouts and raise them if the proxy cuts long-lived responses","Verify the Pi-hole server logs for connection resets"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"resp, err := http.Get(apiURL + \"?version\")\nif err == nil {\n    body, readErr := io.ReadAll(io.LimitReader(resp.Body, 64))\n    if readErr != nil {\n        log.Printf(\"response body unreadable: %v\", readErr)\n    } else {\n        resp.Body.Close()\n    }\n}","typeGuard":null,"tryCatchPattern":"err := retry.Do(func() error {\n    return widget.checkServer(*client, apiUrl)\n}, retry.Attempts(3), retry.Delay(2*time.Second))\nif err != nil {\n    log.Printf(\"Pi-hole response read failed after retries: %v\", err)\n}","preventionTips":["Keep client and Pi-hole on a stable network link","Raise proxy/upstream read timeouts","Watch Pi-hole logs for mid-response connection resets"],"tags":["network","io","pi-hole","http-response"],"backgroundTag":"response-read-failed","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}