wtfutil/wtf · error

invalid request: %s

Error message

invalid request: %s

What it means

checkServer builds a GET request to '<apiUrl>?version' to probe the server. If http.NewRequest fails to construct that request (extremely rare once the URL parses and has a Host), the library reports 'invalid request' with the underlying parseError detail.

Source

Thrown at modules/pihole/client.go:311

func checkServer(c http.Client, apiURL string) error {
	var err error

	var req *http.Request

	var url *url2.URL

	if url, err = url2.Parse(apiURL); err != nil {
		return fmt.Errorf(" failed to parse API URL\n %s", parseError(err))
	}

	if url.Host == "" {
		return fmt.Errorf(" please specify 'apiUrl' in Pi-hole settings, e.g.\n apiUrl: http://<server>:<port>/admin/api.php")
	}

	if req, err = http.NewRequest("GET", fmt.Sprintf("%s?version",
		url.String()), http.NoBody); err != nil {
		return fmt.Errorf("invalid request: %s", parseError(err))
	}

	var resp *http.Response

	if resp, err = c.Do(req); err != nil {
		return fmt.Errorf(" failed to connect to Pi-hole server\n %s", parseError(err))
	}

	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 {

View on GitHub (pinned to bb838c1ccb)

Solutions

  1. Change apiUrl to use http:// or https:// scheme
  2. Re-test with a plain URL like http://<server>:<port>/admin/api.php
  3. Inspect the nested parseError message for the exact request-construction problem

Example fix

// before
apiUrl: ftp://pi.hole/admin/api.php
// after
apiUrl: http://pi.hole/admin/api.php
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(apiURL)
if err != nil {
    return err
}
if u.Scheme != "http" && u.Scheme != "https" {
    return fmt.Errorf("unsupported scheme %q for apiUrl", u.Scheme)
}

Try / catch

if err := widget.checkServer(*client, apiUrl); err != nil {
    if strings.HasPrefix(err.Error(), "invalid request") {
        log.Printf("fix apiUrl scheme/format: %v", err)
    }
}

Prevention

When it happens

Trigger: http.NewRequest("GET", fmt.Sprintf("%s?version", url.String()), http.NoBody) returns an error in checkServer — typically a context/URL issue such as an unsupported scheme after parsing.

Common situations: apiUrl with a scheme Go's http client cannot build a request for (e.g. ftp://), or malformed characters surviving in the parsed URL string.

Related errors


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