wtfutil/wtf · error

Pi-hole server failed to respond %s

Error message

 Pi-hole server failed to respond
 %s

What it means

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.

Source

Thrown at modules/pihole/client.go:336

	}

	defer func() {
		_ = resp.Body.Close()
	}()

	if resp.StatusCode >= http.StatusBadRequest {
		return fmt.Errorf(" failed to retrieve version from Pi-hole server\n http status code: %d",
			resp.StatusCode)
	}

	var vResp struct {
		Version int `json:"version"`
	}

	var rBody []byte

	if rBody, err = io.ReadAll(resp.Body); err != nil {
		return fmt.Errorf(" Pi-hole server failed to respond\n %s", parseError(err))
	}

	if err = json.Unmarshal(rBody, &vResp); err != nil {
		return fmt.Errorf(" invalid response returned from Pi-hole Server\n %s", parseError(err))
	}

	if vResp.Version != 3 {
		return fmt.Errorf(" only Pi-hole API version 3 is supported\n version %d was detected", vResp.Version)
	}

	return err
}

func (widget *Widget) adblockSwitch(action string) {
	var req *http.Request

	var url *url2.URL
	url, _ = url2.Parse(widget.settings.apiUrl)

View on GitHub (pinned to bb838c1ccb)

Solutions

  1. Retry the request; if intermittent, check network stability between client and Pi-hole
  2. Inspect reverse proxy timeouts and raise them if the proxy cuts long-lived responses
  3. Verify the Pi-hole server logs for connection resets
Defensive patterns

Strategy: retry

Validate before calling

resp, err := http.Get(apiURL + "?version")
if err == nil {
    body, readErr := io.ReadAll(io.LimitReader(resp.Body, 64))
    if readErr != nil {
        log.Printf("response body unreadable: %v", readErr)
    } else {
        resp.Body.Close()
    }
}

Try / catch

err := retry.Do(func() error {
    return widget.checkServer(*client, apiUrl)
}, retry.Attempts(3), retry.Delay(2*time.Second))
if err != nil {
    log.Printf("Pi-hole response read failed after retries: %v", err)
}

Prevention

When it happens

Trigger: io.ReadAll(resp.Body) returns an error in checkServer while reading the '<apiUrl>?version' response.

Common situations: Unstable network to the Pi-hole host, server closing the connection mid-transfer, proxy timing out the upstream, or TLS interruptions.

Related errors


AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03). Data as JSON: /api/errors/30557c25dc8ff781. Report an issue: GitHub.